我的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
答案 0 :(得分:4)
我看到了几个问题:
操作模式不匹配。你为CFB(Cipher Feedback)操作模式生成一个IV,你使用ECB(Electronic Code Book - 不推荐,只是查看该wiki文章中的图片了解原因)作为实际加密时的模式,然后尝试使用CBC(Cipher Block Chaining)模式解密。你应该坚持一种模式(可能是CBC)。要执行此操作,请保留解密端aes-256-cbc
并使加密端MCRYPT_MODE_CBC
您将$ salt(实际上是您的密钥)传递给mcrypt_encrypt
而不对其进行哈希处理,但请对其进行哈希处理,并在crypto.createDecipheriv
期望binary
时返回十六进制字符串编码字符串,每its documentation。两个键都需要相同,并且需要遵循正确的编码,以便在传递给函数时它们保持不变。
看起来您在加密端生成IV,然后在解密端使用固定字符串作为IV。需要将IV(初始化向量)与密文通信到解密侧(并且可以与密文一起以明文形式传输)。
解密对象上的update
方法不接受base64
作为编码,每its documentation。您需要将base64文本转换为其他内容(可能是二进制编码),然后使用正确的编码将其传递给更新方法。
PHP的默认字符集是ISO-8859-1,但您尝试将密文解密为UTF-8字符串。这可能会导致问题,尤其是在使用标准ASCII中使用的字符之外的字符时。您需要确保您的PHP端以UTF-8模式运行(请查看this SO answer如何执行此操作),或确保您的输入仅使用ASCII字符(ISO-8859-1是超集) ASCII)并使用'ascii'输出编码。
您的大多数问题归结为编码问题。我对node.js上的各种类型的编码了解不多,所以你需要自己研究,但加密原语的问题应该很容易解决。请务必阅读我链接的文档以及mcrypt_encrypt
documentation。