Search code examples
javascriptphpencryptioncryptojs

cryptojs aes encryption does not match with php


I want to encrypt and decrypt data between client and server so using cryptojs. but cryptojs does work properly

  1. it returns different values every time it runs when using AES but somehow decrypt properly.
  2. encrypted value does not match with php value.

php

$simple_string = "this is my test";
$ciphering = "AES-256-CBC";
$options = 0;
$encryption_iv = '0123456789012345';
$encryption_key = "password";
$encryption = openssl_encrypt($simple_string, $ciphering, $encryption_key, $options, $encryption_iv);

echo "Encrypted String: " . $encryption . " <br>"; //  XkuEMQ6oPwCf4JFb7TlPgw==

$decryption=openssl_decrypt ($encryption, $ciphering, $encryption_key, $options, $encryption_iv);
echo "Decrypted String: " . $decryption; // this is my test

js

    function encrypt(msg, pass, iv) {
        var encrypted = CryptoJS.AES.encrypt(msg, pass, { iv: iv, keySize: 256, mode: CryptoJS.mode.CBC, });
        var decrypted = CryptoJS.AES.decrypt(encrypted, pass, { iv: iv, keySize: 256, mode: CryptoJS.mode.CBC, });

        console.log(encrypted.toString()); // U2FsdGVkX19vi6PRshrz1aB0FSy0q4FNWvl3kkphsHs=
        console.log(decrypted.toString(CryptoJS.enc.Utf8)); // this is my test
    }
    console.log(encrypt("this is my test", "password", "0123456789012345"));

i want javascript function(encrypt and decrypt) for sending and receiving server data using cryptojs.


Solution

  • To make the CryptoJS code compatible with the PHP code, in the CryptoJS code the too short key material must be extended with 0x00 values to the specified key length (note that if the key material were too long, it would simply have to be truncated to the specified key length).
    Since aes-256-cbc is used in the example, it must be extended to 32 bytes and imported into a WordArray using the Latin1 encoder.
    The IV is to be imported into a WordArray in an analogous way:

    console.log(encrypt("this is my test", CryptoJS.enc.Latin1.parse("password".padEnd(32, '\0')), CryptoJS.enc.Latin1.parse("0123456789012345")));
    

    what gives as output:

    XkuEMQ6oPwCf4JFb7TlPgw==
    this is my test
    

    in accordance with the PHP code.