如何解决GO解密nodejs已被弃用的数据加密方法?
这是我接手的一个有4年历史的nodejs项目,我被要求用golang对其进行重构,但是在重构中我发现nodejs加密被弃用了。而且,我不知道使用哪种 AES 模式来加密这段代码
哪位高手能帮我看看如何用golang解密这个nodejs加密?非常感谢!
nodejs 的加密代码:
exports.createtoken = function (src: string,timestamp: string,key: any) {
var msg = src + '|' + timestamp;
var cipher: any = CryptoJS.createCipher('aes256',key);
var enc: any = cipher.update(msg,'utf8','hex');
enc += cipher.final('hex');
return enc;
};
nodejs的解密代码:
exports.parsetoken = function (token: string,key: string): any {
let decipher = CryptoJS.createDecipher('aes256',key);
let dec: string;
try {
dec = decipher.update(token,'hex','utf8');
dec += decipher.final('utf8');
} catch (err) {
console.error('[token] fail to decrypt token. %j',token);
return null;
}
var ts = dec.split('|');
if (ts.length !== 2) {
// illegal token
return null;
}
return { src: ts[0],timestamp: Number(ts[1]) };
};
解决方法
不推荐使用的方法 crypto.createCipher()
和 crypto.createDecipher()
应用专有的 OpenSSL 函数 EVP_BytesToKey()
从密码派生 32 字节的密钥和 16 字节的 IV。不使用盐,摘要 MD5 和迭代次数为 1。此算法非常不安全,这就是不推荐使用这两种方法的原因。
发布的代码应用 aes-256-cbc
(即 CBC 模式下的 AES-256)和仅此密钥派生以派生密钥/IV 对。由于密钥派生不使用盐,因此对于相同的明文和密码,总是得到相同的密文结果。例如。对于:
var src = 'The quick brown fox jumps over the lazy dog';
var timestamp = '1616409134831';
var passphrase = 'my secret passphrase';
密文为:
60673700fb64da36b65829ee3c578d1ec675638a95c8dee4e7c026ee72a837c2170c13b7b24125c02871663a64fd646dd9994793943eeb70b3e959cbc4cd423a
因此,对于 Go 中的解密,您需要实现 EVP_BytesToKey()
,例如here:
package main
import (
"crypto/aes"
"crypto/cipher"
"fmt"
"github.com/walkert/go-evp"
"encoding/hex"
)
func main() {
key,iv := evp.BytesToKeyAES256CBCMD5([]byte(""),[]byte("my secret passphrase")) // MD5,no salt,passprase: my secret passphrase
ciphertext,_ := hex.DecodeString("60673700fb64da36b65829ee3c578d1ec675638a95c8dee4e7c026ee72a837c2170c13b7b24125c02871663a64fd646dd9994793943eeb70b3e959cbc4cd423a")
block,err := aes.NewCipher(key)
if err != nil {
panic(err)
}
cbc := cipher.NewCBCDecrypter(block,iv)
plaintextPadded := make([]byte,len(ciphertext))
cbc.CryptBlocks(plaintextPadded,ciphertext)
plaintext := string(PKCS7Unpad(plaintextPadded ))
fmt.Println("Decrypted data: ",string(plaintext))
}
func PKCS7Unpad(src []byte) []byte { // PKCS7 unpadding from https://stackoverflow.com/a/41595640/9014097
length := len(src)
unpadding := int(src[length-1])
return src[:(length - unpadding)]
}
运行这段代码会得到上面的明文。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。