golang中的windows加密rdp密码

Fuq*_*ang 5 encryption winapi go

http://play.golang.org/p/fD7mx2k4Yc

\n\n

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

\n\n
   package main\n\n    import (\n        "fmt"\n        "log"\n        "syscall"\n        "unsafe"\n    )\n\n    const (\n        CRYPTPROTECT_UI_FORBIDDEN = 0x1\n    )\n\n    var (\n        dllcrypt32  = syscall.NewLazyDLL("Crypt32.dll")\n        dllkernel32 = syscall.NewLazyDLL("Kernel32.dll")\n\n        procEncryptData = dllcrypt32.NewProc("CryptProtectData")\n        procDecryptData = dllcrypt32.NewProc("CryptUnprotectData")\n        procLocalFree   = dllkernel32.NewProc("LocalFree")\n    )\n\n    type DATA_BLOB struct {\n        cbData uint32\n        pbData *byte\n    }\n\n    func NewBlob(d []byte) *DATA_BLOB {\n        if len(d) == 0 {\n            return &DATA_BLOB{}\n        }\n        return &DATA_BLOB{\n            pbData: &d[0],\n            cbData: uint32(len(d)),\n        }\n    }\n\n    func (b *DATA_BLOB) ToByteArray() []byte {\n        d := make([]byte, b.cbData)\n        copy(d, (*[1 << 30]byte)(unsafe.Pointer(b.pbData))[:])\n        return d\n    }\n\n    func Encrypt(data []byte) ([]byte, error) {\n        var outblob DATA_BLOB\n        r, _, err := procEncryptData.Call(uintptr(unsafe.Pointer(NewBlob(data))), 0, 0, 0, 0, 0, uintptr(unsafe.Pointer(&outblob)))\n        if r == 0 {\n            return nil, err\n        }\n        defer procLocalFree.Call(uintptr(unsafe.Pointer(outblob.pbData)))\n        return outblob.ToByteArray(), nil\n    }\n\n    func Decrypt(data []byte) ([]byte, error) {\n        var outblob DATA_BLOB\n        r, _, err := procDecryptData.Call(uintptr(unsafe.Pointer(NewBlob(data))), 0, 0, 0, 0, 0, uintptr(unsafe.Pointer(&outblob)))\n        if r == 0 {\n            return nil, err\n        }\n        defer procLocalFree.Call(uintptr(unsafe.Pointer(outblob.pbData)))\n        return outblob.ToByteArray(), nil\n    }\n\n    func main() {\n        const secret = "MYpasswd"\n        enc, err := Encrypt([]byte(secret))\n        if err != nil {\n            log.Fatalf("Encrypt failed: %v", err)\n        }\n        dec, err := Decrypt(enc)\n        if err != nil {\n            log.Fatalf("Decrypt failed: %v", err)\n        }\n        if string(dec) != secret {\n            log.Fatalf("decrypted secret \\"%s\\" does not match to \\"%s\\".", dec, secret)\n        }\n        fmt.Println(fmt.Sprintf("%x", enc))\n        fmt.Println(string(dec))\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

out: 01000000d08c9ddf0115d1118c7a00c04fc297eb01000000de7c90fbe3c9854381f0a0ffe1d496f3000000000200000000001066000000010000200000000790b641e1a9d4bfe54d81966c4d7aaeabf19b63c36dff42668e3b256edbeed8000000000e8000000002000020000000d6385d3352d5a4b011e171ab25b30271e73a4ddc0b9f9bfb8ecd13f230362a0110000000da71663217c163d7ab77231282e7d8d64000000025fbcbb72efcdc711f3a74c38bddbf0b71538f0ffe27d133c0c5cd2434f88d55d924f598ac2f94758d66a448682ed841fb56ce8c9de38601dcce6bd42aa41fbb

\n\n

我的密码

\n\n

创建 tmp.rdp

\n\n
screen mode id:i:1\n....\nwinposstr:s:0,1,153,64,953,664\nusername:s:{{username}}\ndomain:s:\npassword 51:b:01000000d08c9ddf0115d1118c7a00c04fc297eb0100000............\ndisable wallpaper:i:1\ndisable full window drag:i:1\n
Run Code Online (Sandbox Code Playgroud)\n\n

最终\xef\xbc\x9a \n mstsc.exe tmp.rdp

\n\n

但登录失败

\n\n

python“win32crypt.CryptProtectData”可以工作。

\n\n
    pwdHash = win32crypt.CryptProtectData(u"MYpasswd", u\'pws\', None, None, None, 0)\n    enc_password = binascii.hexlify(pwdHash)\n
Run Code Online (Sandbox Code Playgroud)\n

Fuq*_*ang 1

问题已经解决。

secret = "MYpasswd"
Run Code Online (Sandbox Code Playgroud)

字符串必须使用 UTF-16LE 编码。