猿问

golang中的Windows加密rdp密码

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


window 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

    }


宝慕林4294392
浏览 344回答 2
2回答

紫衣仙女

对上面不详细的答案做一个补充。根据@Fuqiang 的回答,只需UTF-16LE在加密之前将纯字符串的编码传输到,就可以了。所以它看起来像这样:....func convertToUTF16LittleEndianBytes(s string) []byte {&nbsp; &nbsp; u := utf16.Encode([]rune(s))&nbsp; &nbsp; b := make([]byte, 2*len(u))&nbsp; &nbsp; for index, value := range u {&nbsp; &nbsp; &nbsp; &nbsp; binary.LittleEndian.PutUint16(b[index*2:], value)&nbsp; &nbsp; }&nbsp; &nbsp; return b}func main() {&nbsp; &nbsp; const secret = "MYpasswd"&nbsp; &nbsp; s := convertToUTF16LittleEndianBytes(secret)&nbsp; &nbsp; enc, err := Encrypt(s)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; log.Fatalf("Encrypt failed: %v", err)&nbsp; &nbsp; }&nbsp; &nbsp; ...}并且解密后,您必须utf-16le在比较或使用它之前对解密的字符串进行解码,不要直接将utf-16le字符转换为字符串string(dec)。

BIG阳

问题已解决。secret&nbsp;=&nbsp;"MYpasswd"字符串必须使用&nbsp;UTF-16LE&nbsp;编码。
随时随地看视频慕课网APP

相关分类

Go
我要回答