一尘不染

Node.js加密解密有什么问题?

node.js

我有以下加密数据:

U2FsdGVkX1+21O5RB08bavFTq7Yq/gChmXrO3f00tvJaT55A5pPvqw0zFVnHSW1o

对其进行解密的密码是: 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 faildecipher.final一行中遇到以下错误。

我想念什么吗?谢谢。


阅读 348

收藏
2020-07-07

共1个答案

一尘不染

加密的数据以8字节的“魔术”开头,表示存在盐(的ASCII编码"Salted__")。然后接下来的8个字节是盐。现在是个坏消息:Node.js似乎没有对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')

[最新编辑]请注意,使用带有盐和较大工作因子的秘密密钥派生对安全性至关重要。您最好使用非常独特的高熵密码,否则您的加密数据可能会受到威胁。


请[稍后编辑] OpenSSL1.1.0c更改了某些内部组件中使用的摘要算法。以前使用MD5,并且1.1.0切换到SHA256。请注意,更改不会同时影响您EVP_BytesToKey和命令opensslenc

2020-07-07