Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

PHP encrypt and decrypt in node JS

I have a encryption in PHP and a decryption in node JS.
I know there are many topics about this. But all of them state that it doesn’t work.
In my case it does. Well sort of.

PHP

define('CRYPT_KEY', 'bwAZA48aaYd34PGhBWSutIIFaCu4oAe/Ps24/Rx+bw0=');

class Encryption {
  public function encrypt($data) {
    $output = false;
    $methode = "AES-256-CBC";
    $key = base64_decode(CRYPT_KEY);

    $ivSize  = openssl_cipher_iv_length($methode);
    $ivData  = openssl_random_pseudo_bytes($ivSize);
    $encData = openssl_encrypt($data, $methode, $key, OPENSSL_RAW_DATA, $ivData);
    $output = base64_encode($ivData . $encData);

    return $output;
  }

  public function decrypt($data) {
    $output = false;
    $methode = "AES-256-CBC";
    $key = base64_decode(CRYPT_KEY);

    $ivSize  = openssl_cipher_iv_length($methode);
    $data = base64_decode($data);
    $ivData   = substr($data, 0, $ivSize);
    $encData = substr($data, $ivSize);
    $output = openssl_decrypt($encData, $methode, $key, OPENSSL_RAW_DATA, $ivData);

    return $output;
  }
}

echo $encryption->encrypt('Hello world'); 
// output: 8ZtGcgDeSCN8f+jrZ/W2tWL40DIncjmCwanFiNrEhyE=

node JS

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const key = Buffer.from('bwAZA48aaYd34PGhBWSutIIFaCu4oAe/Ps24/Rx+bw0=', 'base64');
const iv = Buffer.from(crypto.randomBytes(16), 'base64');


function decrypt(data) {
  const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
  const decripted = decipher.update(data, 'base64', 'utf8') + decipher.final('utf8');
  
  return decripted;
}

console.log('Output: ', decrypt('8ZtGcgDeSCN8f+jrZ/W2tWL40DIncjmCwanFiNrEhyE='));

the first part of the output is scrambled

result: ▬�2���◄p��r♣�'Hello world

Does someone know why this happens. Im I doing something wrong?

>Solution :

The reason for the problem is that in the PHP code IV and actual ciphertext are concatenated. But in the NodeJS code the separation is missing (instead, a new, random IV is used incorrectly).

The separation of IV and ciphertext can be done as follows:

const data = Buffer.from('tIF2bpl7Ro8lZbslAgBqJNqwIqn4pNWZrGkUaWcJQzo=', 'base64');
const iv = data.subarray(0, 16);
const ciphertext = data.subarray(16);

Since the ciphertext is now passed to decrypt() as buffer and not Base64 encoded, the decryption in decrypt() has to be implemented as follows:

const decripted = decipher.update(data, '', 'utf8') + decipher.final('utf8');

Note that the posted NodeJS example does not work. It returns an EVP_DecryptFinal_ex:bad decrypt error, indicating that the key and ciphertext are not related.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading