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

GO decryption nodejs has been deprecated data encryption method?

这是我接手的一个有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() and crypto.createDecipher() apply the proprietary OpenSSL function EVP_BytesToKey() 从密码派生 32 字节密钥和 16 字节 IV。没有使用盐,摘要MD5和迭代计数为1。这个算法非常不安全,这就是为什么这两种方法都被弃用的原因。

发布的代码应用 aes-256-cbc(即 CBC 模式下的 AES-256)并且仅此密钥派生来派生 key/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 
        length := len(src)
        unpadding := int(src[length-1])
        return src[:(length - unpadding)]
}

运行这段代码产生了上面的明文。