PHP aes-256-cbc mcrypt_decrypt()等效于Node.js [英] PHP aes-256-cbc mcrypt_decrypt() equivalent in Node.js
问题描述
这是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屋!