Encrypt in nodejs and decrypt in php or vice versa

If you are trying to encrypt in php and decrypt in nodejs or vice versa, first thing you need to know is only mcrypt_rijndel_128 is identical with aes-128-cbc. So you must use mcrypt_rijndel_128 for php and aes-128-cbc for nodejs. Crypto module for nodejs provides wide verity of encryption/decryption algorithm. The other thing you should know is key and initializing vector (iv) should be same in php and nodejs.

encrypting in nodejs:

var crypto = require('crypto');
var key = 'MySecretKey12345';
var iv = '1234567890123456';
var cipher = crypto.createCipheriv('aes-128-cbc', key, iv);

var text = 'plain text';
var encrypted = cipher.update(text, 'utf8', 'binary');
encrypted += cipher.final('binary');
hexVal = new Buffer(encrypted, 'binary');
newEncrypted = hexVal.toString('hex');

console.log('Encrypted: ', newEncrypted);

//output: 9eb6c9052d1de4474fb52d829360d5af

Decrypting in php:

private $encryptKey = 'MySecretKey12345';
private $iv = '1234567890123456';
private $blocksize = 16;

public function decrypt($data)
    return $this->unpad(mcrypt_decrypt(MCRYPT_RIJNDAEL_128,
        MCRYPT_MODE_CBC, $this->iv), $this->blocksize);

private function unpad($data, $blocksize)
    $len = mb_strlen($data);
    $pad = ord( $data[$len - 1] );
    if ($pad && $pad < $blocksize) {
        $pm = preg_match('/' . chr( $pad ) . '{' . $pad . '}$/', $data);
        if( $pm ) {
            return mb_substr($data, 0, $len - $pad);
    return $data;

//echo $this->decrypt('9eb6c9052d1de4474fb52d829360d5af')
// output:  plain text

Full version in gist.

  • Acelga Frita

    Thanks Rojan!

    With PHP 7.x mcrypt_decrypt() is deprecated, it would be now:

    return $this->unpad($openssl_decrypt(hex2bin($data), ‘AES-128-CBC’, $this->encryptKey, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->iv), $keySize);