Skip to content
Advertisement

Node.js Crypto lib returning different result from PHP opensll_encrypt lib

My problem is as follows:

I have a PHP script that is responsible for encrypting a string using AES-256-CBC encryption. This script uses the openssl lib and returns an X result.

<?php
class AES
{
    const PRIVATE_KEY =  'abcdefghijklmnnoabcdefghijklmnno';
    const ENCRYPT_METHOD = 'aes-256-cbc';
    const VECTOR = 'abcdefghijklmnno';

    public function encryptData($data)
    {
        while(strlen($data) < 16) $data .= "";
        return openssl_encrypt($data, self::ENCRYPT_METHOD, self::PRIVATE_KEY, OPENSSL_ZERO_PADDING, self::VECTOR);
    }

  public function encryptDataL($data)
    {
        return openssl_encrypt($data, self::ENCRYPT_METHOD, self::PRIVATE_KEY, 0, self::VECTOR);
    }
    
    public function decryptData($data)
    {
        return openssl_decrypt($data, self::ENCRYPT_METHOD, self::PRIVATE_KEY, OPENSSL_ZERO_PADDING, self::VECTOR);
    }

}

$aes = new AES();
echo $aes->encryptData("abcdefghijkl");
echo "n";
echo $aes->encryptDataL("{"REQUEST": [{"MSISDN": "32156489721","IDPRODUCT": 123,"IDOPERATOR": 12345,"OUTPUTFORMAT": "JSON"}],"OUTPUTFORMAT": "json"}");
?>

when I run a JS script, responsible for doing the same, but using the Crypto lib, the result obtained is different from the previous X.

const crypto = require('crypto');
const cipher = crypto.createCipheriv('aes-256-cbc', 'abcdefghijklmnnoabcdefghijklmnno', 'abcdefghijklmnno');
let crypted = cipher.update(data, 'utf8', 'base64');
crypted += cipher.final('base64');

The results of the scripts differ, even though, in theory, the encryption should be the same.

An example of return is as follows:

  • For the php script: input -> ^y3Hk3JKGGgA output -> eTqD5Op389QS/TOoui5kAQ==

  • For the js script: input -> ^y3Hk3JKGGgA output -> HHfskOE1N+QxdGt9MTai5A==

The desired result is the PHP script, but I need to run the code in JS, can someone explain to me what I may be doing wrong?

I tried different ways to execute the createCipheriv method, but they all return the same result (different from what I need, which is the result obtained through the PHP script)

Thank you in advance.

Advertisement

Answer

Thank you guys for trying to help, indeed I posted the question lacking some informations (actually when the question was made I didn’t have all the pieces of information I needed).

But posting here some facts and the solution encountered for my case.

The different results in the cases above only happen for the first PHP function (“encryptData”), responsible for encrypting small texts. The second, responsible for encrypting large texts (more than 16 bits) worked fine, both in PHP and JS scripts.

The solution I encountered was making the padding needed for the AES-256 algorithm by myself. The padding function provided by the Crypto lib didn’t work, at least for my case.

So I disabled the padding in my cypher class and make sure that the data sent to be encrypted was padded correctly until the length is multiple of 16. The end’s code is below.

encryptWithAES256(data) {
// added padding until data length is multiple of 16
let paddedData = data;
while (paddedData.length % 16 !== 0) {
  paddedData += '';
}

// ciphers data
const cipher = crypto.createCipheriv('aes-256-cbc', encodeKey, IV);
cipher.setAutoPadding(false);
let crypted = cipher.update(paddedData, 'utf8', 'base64');
crypted += cipher.final('base64');
return crypted;

}

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement