16

我有以下加密数据:

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行有以下错误。

我错过了什么吗?谢谢。

4

1 回答 1

17

加密数据以一个 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 测试应用程序(使用正确的 salt)进行了验证 - 返回了结果字符串。

请使用 OpenSSL-nosalt开关忽略盐,然后重试。

[例子]

OpenSSL 命令行:

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')

[后期编辑] 请注意,使用带有盐和大工作因子的密钥派生可能对安全性至关重要。您最好使用一个非常独特的高熵密码,否则您的加密数据可能会面临风险。


[真正晚编辑] OpenSSL 1.1.0c 更改了一些内部组件中使用的摘要算法。以前使用MD5,1.1.0改用SHA256。请注意,更改不会影响您EVP_BytesToKeyopenssl enc.

于 2012-09-11T22:10:54.750 回答