我有以下加密数据:
U2FsdGVkX1+21O5RB08bavFTq7Yq/gChmXrO3f00tvJaT55A5pPvqw0zFVnHSW1o
解密它的通道是:password
(这是gibberish-aes的例子)
在使用openssl的命令行中:
echo "U2FsdGVkX1+21O5RB08bavFTq7Yq/gChmXrO3f00tvJaT55A5pPvqw0zFVnHSW1o" | openssl enc -d -aes-256-cbc -a -k password
输出结果为:
Made with Gibberish\n
使用我的NodeJS应用程序:
var decipher = crypto.createDecipher('aes-256-cbc', "password");
var dec = decipher.update("U2FsdGVkX1+21O5RB08bavFTq7Yq/gChmXrO3f00tvJaT55A5pPvqw0zFVnHSW1o",
'base64', 'utf8');
dec += decipher.final('utf8');
我在TypeError: DecipherFinal fail
行有decipher.final
个错误。
我错过了什么吗?感谢。
答案 0 :(得分:15)
加密数据以8字节“魔术”开头,表示存在盐("Salted__"
的ASCII编码)。然后接下来的8个字节是盐。现在坏消息:Node.js似乎没有使用salt作为EVP_BytesToKey方法:
int key_len = EVP_BytesToKey(cipher, EVP_md5(), NULL,
(unsigned char*) key_buf, key_buf_len, 1, key, iv);
NULL
是盐。
使用Java测试应用程序(使用正确的盐)验证了这一点 - 返回了结果字符串。
请使用OpenSSL -nosalt
开关取出盐,然后重试。
[实施例]
OpenSSL CLI:
openssl enc -aes-256-cbc -nosalt -a -k password
owlstead
Mh5yxIyZH+fSMTkSgkLa5w==
NodeJS加密:
var crypto=require('crypto')
var cipher=crypto.createDecipher('aes-256-cbc', "password")
var enc = cipher.update("Mh5yxIyZH+fSMTkSgkLa5w==", 'base64', 'utf8')
enc += cipher.final('utf8')
[LATE EDIT]请注意,使用带有盐和大工作因子的密钥派生可能对安全性至关重要。您最好使用非常独特的高熵密码,否则您的加密数据可能会有风险。
[真正的编辑] OpenSSL 1.1.0c changed the digest algorithm在一些内部组件中使用。以前使用MD5,1.1.0切换到SHA256。请注意,更改不会影响EVP_BytesToKey
和openssl enc
等命令。