3

我的 PHP 加密看起来像这样:

<?
$salt = '…';
$data = '…';

$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CFB), MCRYPT_RAND);
$ciphered = trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $salt, $data, MCRYPT_MODE_ECB,$iv)));

我试图破译上面代码的结果:

ciphered = '…';
crypto = require('crypto');
salt = crypto.createHash('md5').update('…').digest('hex');
iv = '0123456789123455';
decipher = crypto.createDecipheriv('aes-256-cbc', salt, iv);
deciphered = decipher.update(ciphered, 'base64');
deciphered += decipher.final('utf-8');

此代码导致:TypeError: DecipherFinal fail

4

1 回答 1

4

我看到了几个问题:

  1. 操作模式的不匹配。您为 CFB(密码反馈)操作模式生成 IV,您在实际加密时使用 ECB(电子密码本- 不推荐,只需查看该 wiki 文章中的图像了解原因)作为您的模式,然后尝试使用解密CBC(密码块链接)模式。您应该坚持一种模式(可能是 CBC)。为此,请保留解密端aes-256-cbc并制作加密端MCRYPT_MODE_CBC

  2. 根据其文档,您将 $salt (实际上是您的密钥)传递给mcrypt_encrypt而不对其进行散列,但对其进行散列,并在crypto.createDecipheriv需要binary编码字符串时返回一个十六进制字符串。两个键必须相同,并且需要遵循正确的编码,以便在传递给函数时它们保持相同。

  3. 看起来您在加密端生成了一个 IV,然后在解密端使用一个固定字符串作为 IV。IV(初始化向量)需要与密文一起传递给解密方(可以与密文一起明文传输)。

  4. 根据其文档,您的 decipher 对象上的update方法不接受base64作为编码。您需要将 base64 文本转换为其他内容(可能是二进制编码),然后使用正确的编码将其传递给更新方法。

  5. PHP 的默认字符集是 ISO-8859-1,但您正试图将密文解密为 UTF-8 字符串。这可能会导致问题,尤其是当您使用标准 ASCII 以外的字符时。你要么需要确保你的 PHP 端在 UTF-8 模式下运行(查看这个关于如何做到这一点的 SO 答案),要么确保你的输入只使用 ASCII 字符(ISO-8859-1 是 ASCII 的超集) 并使用 'ascii' 输出编码。

您的大多数问题归结为编码问题。我不太了解 node.js 上的各种编码类型,因此您需要自行研究,但加密原语的问题应该很容易解决。确保阅读我链接的mcrypt_encrypt 文档以及文档。

于 2013-01-29T05:01:32.097 回答