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.
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
);
}
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});
# 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!
// 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);
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With