PHP aes-256-cbc mcrypt_decrypt () equivalent in Node.js

I am trying to port this working php code to Node.js but I am getting 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);

      

+3


source to share


3 answers


MCRYPT_RIJNDAEL_256

refers to the rijndael cipher algorithm with a custom block size of bits 256

, not the key size in bits 256

. PHP uses libmcrypt

for its encryption, and Node.js uses openssl

, and while libmcrypt implements AES (128-bit block size), it also implements rijndael with a configurable block size.

AES is definitely defined with a block size of 128 bits and it is the only version of rijndael openssl support. So I wrote a minimal libmcrypt binding for node called node-rijndael that 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+$/, '');

      

+3


source


Try something like this for node.js:



var aes_iv_b = new Buffer(aes_iv, 'base64'),
    shared_key_b = new Buffer(shared_key, 'hex'),
    decipher = crypto.createDecipheriv('aes-256-cbc', shared_key_b, aes_iv_b),
    decoded = Buffer.concat([
      decipher.update(payload, 'base64'),
      decipher.final()
    ]);
// if the output is utf8/ascii you might be able to improve performance by using
// something like this instead:
//  decoded = decipher.update(payload, 'base64', 'utf8') // or 'ascii'
//            + decipher.final('utf8'); // or 'ascii'

console.log(decoded);

      

0


source


If you can change the PHP code to use openssl

with aes-256-cbc

instead libmcrypt

, you can use the standard library crypto

as I used in this other answer

Hope this helps. Sincerely, Ignacio

0


source







All Articles