javascript - 在 node.js 中重新创建 MCRYPT_RIJNDAEL_128

标签 javascript php node.js aes mcrypt

尝试在 node.js 中重新创建以下 php 加密代码:

$size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($size, MCRYPT_RAND);
$msg = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, 'MY_KEY_LONG_STRING', 'PLAINTEXT', MCRYPT_MODE_ECB, $iv));

试过这个:

var text = 'PLAINTEXT';
var len = text.length;
for (var i = 0; i < 16 - len % 16; i++) {  // pad to multiple of block size 
    text += '\0';
}
var key = 'MY_KEY_LONG_STRING';
key = key.substr(0, 16); // trim to expected key size for aes128

var cipher = crypto.createCipher('aes-128-ecb', key);
cipher.setAutoPadding(false); // did our own padding, to match mcrypt_encrypt
var encrypted = cipher.update(text, 'utf8', 'base64');
encrypted += cipher.final('base64');

从 php 得到不同的结果...

还尝试使用 IV 创建密码(甚至不应该在 aes-128-ecb 中使用):

var cipher = crypto.createCipheriv('aes-128-ecb', key, '');

此外,与 php.ini 的结果不同。任何想法如何使它的行为与 php 版本完全一样?

最佳答案

让两个构造相当糟糕的库相互对战会很有趣。我不会完成所有工作,而是会根据要求帮助您提出想法:

  • PHP 不是删除 key 字节,而是使用零填充将它们扩展到下一个可用的 key 大小——在您的情况下是 192 位或 24 字节;为此,您需要将 aes-192-ecb 指定为算法(您需要继续使用 MCRYPT_RIJNDAEL_128 但替代,PHP 中的 128 是 block 大小而不是 key 大小)
  • 填充不正确,PHP 填充 0..15 个零字节而不是 1..16 个字节
  • 您不能使用第二个参数 createCipher 因为第二个参数是密码;如果您使用 node.js 执行 key 派生,因此您需要使用三个参数 createCipher 并提供任何 16 字节 IV

PHP 中的 IV 代码只会对随机数生成器产生不必要的负担,不会使用 IV。


填充代码

var padSize = 16 - ((len + 16 - 1) % 16 + 1);
for (var i = 0; i < padSize; i++) {  // pad 0 .. 15 until to multiple of block size 
    text += '\0';
}

或者您可以使用自己的填充方法(在问题中)除非 len % 16 == 0

关于javascript - 在 node.js 中重新创建 MCRYPT_RIJNDAEL_128,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27714694/

相关文章:

regex - 如何创建处理如下 URL 的 Express 路由?

javascript - 使用 jQuery 只查找头等舱

javascript - 使用 Javascript 将可扩展表导出为 CSV

php - 如何对mysql数据进行反向排序

node.js - 在 WebStorm 中设置 Node.js 环境变量

javascript - Electron :加载外部脚本并将其传递给函数

javascript - href 链接中的哈希值将发送到 Controller

javascript - 使用 jQuery 检查用户是否滚动到 div 底部

php - 未传输 session 变量

php - Laravel PayPal 支付返回 400