PHP aes-256-cbc mcrypt_decrypt()等效于Node.js [英] PHP aes-256-cbc mcrypt_decrypt() equivalent in Node.js

查看:277
本文介绍了PHP aes-256-cbc mcrypt_decrypt()等效于Node.js的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将此工作的PHP代码移植到Node.js,但是我收到错误:无效IV长度32



这是PHP代码:

  // --- PHP示例代码(作品):--- 

$ aes_iv ='MjY2YjljMmM0MjVjNzVlMGMyZGI2NjAwN2U5ZGMzZDQ% 3D';

$ payload = base64_decode($ payload);
$ aes_iv = base64_decode($ aes_iv);

//秘密密钥。 64个字符的十六进制字符串:
$ shared_key ='14370ced836 ...';
//从hex转换为二进制字符串:
$ shared_key = pack('H *',$ shared_key);

// AES解密有效负载
$ payload = mcrypt_decrypt(MCRYPT_RIJNDAEL_256,$ shared_key,$ payload,MCRYPT_MODE_CBC,$ aes_iv);


// AES将空字符添加到短字符串的末尾,
//所以我们应该将它们删除
$ payload = rtrim($ tp_payload, \0\" );

这是Node.js代码不起作用。
请参阅错误:无效IV长度32

  // --- Node.js等效? --- 

var aes_iv ='MjY2YjljMmM0MjVjNzVlMGMyZGI2NjAwN2U5ZGMzZDQ%3D';

var payload_s = new Buffer(payload,'base64')。toString();
var aes_iv_s = new Buffer(aes_iv,'base64')。toString();

//秘密密钥。 64个字符的十六进制字符串:
var shared_key ='14370ced836 ...';
//从hex转换为二进制字符串:
var shared_key_b = new Buffer(shared_key,'hex')。toString('binary');

//错误:无效IV长度32
var decipher = crypto.createDecipheriv('aes-256-cbc',shared_key_b,aes_iv_s);
var decoding = decipher.update(payload_s);

decoder + = decipher.final();
console.log(已解码);


解决方案

MCRYPT_RIJNDAEL_256 是指具有 256 位的非标准块大小的rijndael加密算法,而不是密钥大小 256 位。 PHP使用 libmcrypt 进行加密,而Node.js使用 openssl ,而libmcrypt实现AES(块大小为128位),它还实现具有可配置块大小的rijndael。



AES具有128位的块大小的特定定义,这是rijndael openssl支持的唯一版本。因此,我为节点 node-rijndael 编写了一个最小的libmcrypt绑定,它应该为您的目的。另见我的答案一个类似的问题这里

  var Rijndael = require('node-rijndael'); 

// shared_key
var key ='14370ced836 ...';

// aes_iv
var iv = new Buffer('MjY2YjljMmM0MjVjNzVlMGMyZGI2NjAwN2U5ZGMzZDQ =','base64');

var payload = new Buffer(/ * payload * /);

var rijndael = new Rijndael(key,{
mode:Rijndael.MCRYPT_MODE_CBC,
encoding:'hex',// shared_key encoding
iv:iv
});

//默认为utf-8输出编码
payload = rijndael.decrypt(payload);
payload = payload.replace(/ \0 + $ /,'');


I'm trying to port this working php code to Node.js but I get Error: Invalid IV length 32

Here is the PHP code:

//--- PHP example code (works): ---

$aes_iv = 'MjY2YjljMmM0MjVjNzVlMGMyZGI2NjAwN2U5ZGMzZDQ%3D';

$payload = base64_decode($payload);
$aes_iv = base64_decode($aes_iv);

// secret key. 64 character hex string:
$shared_key = '14370ced836 ...'; 
// convert from hex to binary string:
$shared_key = pack('H*', $shared_key); 

// AES decrypt payload
$payload = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $shared_key, $payload, MCRYPT_MODE_CBC, $aes_iv);


// AES adds null characters to the end of short strings, 
// so we should strip them out
$payload = rtrim($tp_payload, "\0"); 

Here is the Node.js code that doesn't work. See "Error: Invalid IV length 32"

//--- Node.js equivalent ??? ---

var aes_iv = 'MjY2YjljMmM0MjVjNzVlMGMyZGI2NjAwN2U5ZGMzZDQ%3D';

var payload_s = new Buffer(payload, 'base64').toString();
var aes_iv_s = new Buffer(aes_iv, 'base64').toString();

// secret key. 64 character hex string:
var shared_key = '14370ced836 ...'; 
// convert from hex to binary string:
var shared_key_b = new Buffer(shared_key, 'hex').toString('binary');

// Error: Invalid IV length 32
var decipher = crypto.createDecipheriv('aes-256-cbc', shared_key_b, aes_iv_s);
var decoded  = decipher.update(payload_s);

decoded += decipher.final();
console.log(decoded);

解决方案

MCRYPT_RIJNDAEL_256 refers to the rijndael encryption algorithm with a non-standard block size of 256 bits, rather than a key size of 256 bits. PHP uses libmcrypt for its encryption, while Node.js uses openssl, and while libmcrypt implements AES (block size of 128 bits), it also implements rijndael with configurable block size.

AES is specifically defined with a block size of 128 bits, and that is the only version of rijndael openssl supports. As such, I wrote a minimal libmcrypt binding for node called node-rijndael, which should serve your purposes. See also my answer to a similar question here.

var Rijndael = require('node-rijndael');

// shared_key
var key = '14370ced836...';

// aes_iv
var iv = new Buffer('MjY2YjljMmM0MjVjNzVlMGMyZGI2NjAwN2U5ZGMzZDQ=', 'base64');

var payload = new Buffer(/*payload*/);

var rijndael = new Rijndael(key, {
  mode: Rijndael.MCRYPT_MODE_CBC,
  encoding: 'hex', // shared_key encoding
  iv: iv
});

// defaults to utf-8 output encoding
payload = rijndael.decrypt(payload);
payload = payload.replace(/\0+$/, '');

这篇关于PHP aes-256-cbc mcrypt_decrypt()等效于Node.js的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆