2015-11-04 148 views
0

http://play.golang.org/p/fD7mx2k4Yc窗戶golang加密RDP密碼

窗口RDP密碼加密http://www.remkoweijnen.nl/blog/2007/10/18/how-rdp-passwords-are-encrypted/

package main 

    import (
     "fmt" 
     "log" 
     "syscall" 
     "unsafe" 
    ) 

    const (
     CRYPTPROTECT_UI_FORBIDDEN = 0x1 
    ) 

    var (
     dllcrypt32 = syscall.NewLazyDLL("Crypt32.dll") 
     dllkernel32 = syscall.NewLazyDLL("Kernel32.dll") 

     procEncryptData = dllcrypt32.NewProc("CryptProtectData") 
     procDecryptData = dllcrypt32.NewProc("CryptUnprotectData") 
     procLocalFree = dllkernel32.NewProc("LocalFree") 
    ) 

    type DATA_BLOB struct { 
     cbData uint32 
     pbData *byte 
    } 

    func NewBlob(d []byte) *DATA_BLOB { 
     if len(d) == 0 { 
      return &DATA_BLOB{} 
     } 
     return &DATA_BLOB{ 
      pbData: &d[0], 
      cbData: uint32(len(d)), 
     } 
    } 

    func (b *DATA_BLOB) ToByteArray() []byte { 
     d := make([]byte, b.cbData) 
     copy(d, (*[1 << 30]byte)(unsafe.Pointer(b.pbData))[:]) 
     return d 
    } 

    func Encrypt(data []byte) ([]byte, error) { 
     var outblob DATA_BLOB 
     r, _, err := procEncryptData.Call(uintptr(unsafe.Pointer(NewBlob(data))), 0, 0, 0, 0, 0, uintptr(unsafe.Pointer(&outblob))) 
     if r == 0 { 
      return nil, err 
     } 
     defer procLocalFree.Call(uintptr(unsafe.Pointer(outblob.pbData))) 
     return outblob.ToByteArray(), nil 
    } 

    func Decrypt(data []byte) ([]byte, error) { 
     var outblob DATA_BLOB 
     r, _, err := procDecryptData.Call(uintptr(unsafe.Pointer(NewBlob(data))), 0, 0, 0, 0, 0, uintptr(unsafe.Pointer(&outblob))) 
     if r == 0 { 
      return nil, err 
     } 
     defer procLocalFree.Call(uintptr(unsafe.Pointer(outblob.pbData))) 
     return outblob.ToByteArray(), nil 
    } 

    func main() { 
     const secret = "MYpasswd" 
     enc, err := Encrypt([]byte(secret)) 
     if err != nil { 
      log.Fatalf("Encrypt failed: %v", err) 
     } 
     dec, err := Decrypt(enc) 
     if err != nil { 
      log.Fatalf("Decrypt failed: %v", err) 
     } 
     if string(dec) != secret { 
      log.Fatalf("decrypted secret \"%s\" does not match to \"%s\".", dec, secret) 
     } 
     fmt.Println(fmt.Sprintf("%x", enc)) 
     fmt.Println(string(dec)) 
    } 

出來: 01000000d08c9ddf0115d1118c7a00c04fc297eb01000000de7c90fbe3c9854381f0a0ffe1d496f3000000000200000000001066000000010000200000000790b641e1a9d4bfe54d81966c4d7aaeabf19b63c36dff42668e3b256edbeed8000000000e8000000002000020000000d6385d3352d5a4b011e171ab25b30271e73a4ddc0b9f9bfb8ecd13f230362a0110000000da71663217c163d7ab77231282e7d8d64000000025fbcbb72efcdc711f3a74c38bddbf0b71538f0ffe27d133c0c5cd 2434f88d55d924f598ac2f94758d66a448682ed841fb56ce8c9de38601dcce6bd42aa41fbb

密碼MyPassWd

創建tmp.rdp

screen mode id:i:1 
.... 
winposstr:s:0,1,153,64,953,664 
username:s:{{username}} 
domain:s: 
password 51:b:01000000d08c9ddf0115d1118c7a00c04fc297eb0100000............ 
disable wallpaper:i:1 
disable full window drag:i:1 

決賽: 的mstsc.exe tmp.rdp

但登錄失敗

python「win32crypt.CryptProtectData」是工作。

pwdHash = win32crypt.CryptProtectData(u"MYpasswd", u'pws', None, None, None, 0) 
    enc_password = binascii.hexlify(pwdHash) 
+1

它是如何在'.rdp文件'中不起作用的?你用什麼來打開'.rdp'文件?你會得到什麼? – andlabs

+0

對不起,我提供了更詳細的信息.look new posts –

回答

0

該問題已解決。

secret = "MYpasswd" 

字符串必須使用UTF-16LE編碼。

+0

如何請做好嗎? – Eric

0

爲以上未詳細解答做了補充。根據傅強的回答,只需在加密前將普通字符串的編碼轉換爲UTF-16LE即可,終於有效。所以它看起來像這樣:

.... 

func convertToUTF16LittleEndianBytes(s string) []byte { 
    u := utf16.Encode([]rune(s)) 
    b := make([]byte, 2*len(u)) 
    for index, value := range u { 
     binary.LittleEndian.PutUint16(b[index*2:], value) 
    } 
    return b 
} 

func main() { 
    const secret = "MYpasswd" 
    s := convertToUTF16LittleEndianBytes(secret) 
    enc, err := Encrypt(s) 
    if err != nil { 
     log.Fatalf("Encrypt failed: %v", err) 
    } 
    ... 
} 

和解密後,你有比較或使用它之前從utf-16le解密的字符串解碼,不直接通過string(dec)utf-16le字符傳遞給字符串。