Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AES encrypt in PHP with OpenSSL / decrypt in Node.js

I'm working on a symmetric encryption with OpenSSL using PHP and Nodejs. PHP uses the OpenSSL library, and Node.js decryption is based on the implemented crypto. The problem is that the decrypted text in Node.js is only partially correct.

PHP function for encryption

function encrypt($text, $pw, $base64 = true) {

    $method = 'aes-256-cbc';
    $iv_len = openssl_cipher_iv_length($method);
    $iv = openssl_random_pseudo_bytes($iv_len);
    
    $pw = substr(md5($pw),0,32);

    $cipher =  openssl_encrypt ($text ,$method ,$pw ,!$base64 ,$iv );

    if($base64) {
            $pw = base64_encode($pw);
            $iv = base64_encode($iv);
        }

    return array(
        'iv' => $iv,
        'pw' => $pw,
        'text' => $text,
        'cipher' => $cipher
    );
}

Decryption in nodejs

var cipher = new Buffer(data.cipher, 'base64');
var iv = new Buffer(data.iv, 'base64');
// the password is the same returned by the php function, so 100% correct
var key = new Buffer(data.pw, 'base64');
            
var dec = crypto.createDecipheriv('aes-256-cbc',key,iv);
var dec_data = dec.update(cipher,'binary','utf8');
    
// the script is based on socket.io 
socket.emit('debug',{decrypted : dec_data});

The result

# Encrypting in php...
>> encrypt('1. Lorem ipsum dolor sit amet! 2. Lorem ipsum dolor sit amet!', 'password');

# ...makes nodejs giving me something like
>> 1, 6+r@o ipsum /olor sit amet! 2. Lorem ipsum do

I'm guessing the problem might have something to do with padding - but to be honest: I have no idea.

Thanks for reading an help!

like image 399
HenningCash Avatar asked Aug 19 '12 15:08

HenningCash


People also ask

How do I encrypt and decrypt data in node JS?

// crypto module const crypto = require("crypto"); const algorithm = "aes-256-cbc"; // generate 16 bytes of random data const initVector = crypto. randomBytes(16); // protected data const message = "This is a secret message"; // secret key generate 32 bytes of random data const Securitykey = crypto. randomBytes(32);

Does OpenSSL use AES?

what is AES? AES — Advanced Encryption Standard (also known as Rijndael), is a symmetric-key algorithm which means it uses the same key during encryption/decryption. Symmetric key encryption is performed using the enc operation of OpenSSL.


1 Answers

In your Node code, you are missing the final part of the message:

var dec = crypto.createDecipheriv('aes-256-cbc',key,iv);
var dec_data = dec.update(cipher,'base64','utf8') + dec.final('utf8');

Also, use base64 for your decoding, not binary (because its probably that you'll fall in the scenario mentioned here https://stackoverflow.com/a/8770975/3739618)

I have this sample code working in this other post, please check it out: https://stackoverflow.com/a/28181444/3739618

Regards, Ignacio

like image 76
inieto Avatar answered Sep 24 '22 02:09

inieto