我有以下加密数据:
U2FsdGVkX1+21O5RB08bavFTq7Yq/gChmXrO3f00tvJaT55A5pPvqw0zFVnHSW1o
对其进行解密的密码是: password
password
(这是来自胡言乱语的例子)
在命令行中使用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一行中遇到以下错误。
TypeError: DecipherFinal fail
decipher.final
我想念什么吗?谢谢。
加密的数据以8字节的“魔术”开头,表示存在盐(的ASCII编码"Salted__")。然后接下来的8个字节是盐。现在是个坏消息:Node.js似乎没有对EVP_BytesToKey方法使用盐:
"Salted__"
int key_len = EVP_BytesToKey(cipher, EVP_md5(), NULL, (unsigned char*) key_buf, key_buf_len, 1, key, iv);
那NULL是盐。
NULL
已使用Java测试应用程序(使用正确的盐)对此进行了验证-返回了结果字符串。
请使用OpenSSL -nosalt开关保留盐,然后重试。
-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')
[最新编辑]请注意,使用带有盐和较大工作因子的秘密密钥派生对安全性至关重要。您最好使用非常独特的高熵密码,否则您的加密数据可能会受到威胁。
请[稍后编辑] OpenSSL1.1.0c更改了某些内部组件中使用的摘要算法。以前使用MD5,并且1.1.0切换到SHA256。请注意,更改不会同时影响您EVP_BytesToKey和命令opensslenc。
EVP_BytesToKey
opensslenc