dotcraq3249 2015-10-22 13:57
浏览 88
已采纳

Golang解密使用Node.js加密的字符串

I have a bunch passwords for an internal app that were encrypted with node.js and stored (irrelevantly) in mongodb. I would like to convert this application to Go, but I'm getting tripped up on the node.js encryption. I've looked through the node.js source code for this, and it's using the OpenSSL evpBytesToKey method. I've found a Golang implementation of this on the web, but I still can't decrypt the password in Go that was encrypted with node.js. "algo" is "aes256"

this.encrypt = function(s){
var cipher = crypto.createCipher(algo, key);

var i = 0;
var encrypted = "";
while (i < s.length){
    var end = Math.min(s.length-i, 15);
    var chunk = s.substring(i, end+i);
    encrypted += cipher.update(chunk, "utf8", "base64");
    i+= end;
}

encrypted += cipher.final("base64");
encrypted = encrypted.replace(/\//g,"_").replace(/\+/g, "-"); // base64 url encode
return encrypted;
}

And the Go code:

func evpBytesToKey(password string, keyLen int) (key []byte, iv []byte) {
const md5Len = 16

cnt := (keyLen-1)/md5Len + 1
m := make([]byte, cnt*md5Len)
key = make([]byte, keyLen)
iv = make([]byte, md5Len)


copy(m, md5sum([]byte(password)))

// Repeatedly call md5 until bytes generated is enough.
// Each call to md5 uses data: prev md5 sum + password.
d := make([]byte, md5Len+len(password))
start := 0
for i := 1; i < cnt; i++ {
    start += md5Len
    copy(d, m[start-md5Len:start])
    copy(d[md5Len:], password)
    copy(m[start:], md5sum(d))
}
return m[:keyLen], iv
}

And the decrypt function

func Decrypt(key string, b64 string) string {
text := decodeBase64(b64)   // base64.StdEncoding.DecodeString helper method
block, err := aes.NewCipher(evpBytesToKey(key,32))
if err != nil {
    panic(err)
}
if len(text) < aes.BlockSize {
    panic("ciphertext too short")
}
iv := text[:aes.BlockSize]
text = text[aes.BlockSize:]

fmt.Println(iv)
fmt.Println(text)

cfb := cipher.NewCFBDecrypter(block, iv)
cfb.XORKeyStream(text, text)
return string(text)
}

Here is some sample data:

8PTcrR0Nf0sltmdtvLUrFg== (you tell ME what it decrypts to :)

The key is var key = "random array of characters"; literally.

This is above my personal encryption experience and training. It is my last roadblock... Thanks for any help and guidance you can provide.

  • 写回答

1条回答 默认 最新

  • duanhan9334 2015-10-22 21:00
    关注

    In OpenSSL 'aes256' is equivalent to 'aes-256-cbc'. So your use of NewCFBDecrypter seems off. Other than that the IV/key generation needed to be tweaked a little to actually generate an IV.

    This test script gives me an output that's at least ASCII.

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

    I found the IV / key to look for by having OpenSSL generate it for me (made debugging genIvAndKey a little easier).

    Note that you still need to determine where to split between the actual password and the padding. (unicode.IsPrint?)

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 VSCode里的Prettier如何实现等式赋值后的对齐效果?
  • ¥15 流式socket文件传输答疑
  • ¥20 keepalive配置业务服务双机单活的方法。业务服务一定是要双机单活的方式
  • ¥50 关于多次提交POST数据后,无法获取到POST数据参数的问题
  • ¥15 win10,这种情况怎么办
  • ¥15 如何在配置使用Prettier的VSCode中通过Better Align插件来对齐等式?(相关搜索:格式化)
  • ¥100 在连接内网VPN时,如何同时保持互联网连接
  • ¥15 MATLAB中使用parfor,矩阵Removal的有效索引在parfor循环中受限制
  • ¥20 Win 10 LTSC 1809版本如何无损提升到20H1版本
  • ¥50 win10 LTSC 虚拟键盘不弹出