微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

GO解密nodejs已被弃用的数据加密方法?

如何解决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 举报,一经查实,本站将立刻删除。