encrypt in PHP just like javascript CryptoJS

All we need is an easy explanation of the problem, so here it is.

I have javascript that encrypts and gives the string.
But I have to do this through PHP.
The method I have tried is giving me different result than javascript.

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js" 
            integrity="sha512-nOQuvD9nKirvxDdvQ9OMqe2dgapbPB7vYAMrzJihw5m+aNcf0dX53m6YxM4LgA9u8e9eg9QX+/+mPu8kCNpV2A==" crossorigin="anonymous"></script>

var txt="This text will be encrypted.";
var key = CryptoJS.enc.Hex.parse('0123456789abcdef0123456789abcdef');
var iv  = CryptoJS.enc.Hex.parse('abcdef9876543210abcdef9876543210');
var encrypted = CryptoJS.AES.encrypt((txt), key, { iv: iv });
var encrypted_data = encrypted.ciphertext.toString(CryptoJS.enc.Base64);
alert(encrypted_data);

I get output:
2X/btHgrMBhNlgD8oKNO9rzqCg+RSydprVKmpbYY+j0=

In PHP

<?php
$plaintext="This text will be encrypted.";
$key = pack("H*", "0123456789abcdef0123456789abcdef");
$iv =  pack("H*", "abcdef9876543210abcdef9876543210");
    
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $iv);
$ciphertext_base64 = base64_encode($ciphertext);
echo $ciphertext_base64;
?>

I get output:
2X/btHgrMBhNlgD8oKNO9nJyd4xC4VTLGxnnrzGim+U=

I want the out as same as the output in javascript.
I found that the starting 21 characters match, but not the rest of the string.
Anything I am missing?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

This is due to the different padding. CryptoJS uses PKCS#7, mcrypt applies zero padding.

You should replace mcrypt on the PHP side as it is deprecated (s. here). An alternative would be PHP/OpenSSL, which uses PKCS#7 by default.

A solution with PHP/OpenSSL which produces the same ciphertext is:

<?php
$plaintext="This text will be encrypted.";
$key = hex2bin("0123456789abcdef0123456789abcdef");
$iv =  hex2bin("abcdef9876543210abcdef9876543210");
    
$ciphertext_base64 = openssl_encrypt($plaintext, "aes-128-cbc", $key, 0, $iv);
echo $ciphertext_base64; // 2X/btHgrMBhNlgD8oKNO9rzqCg+RSydprVKmpbYY+j0=
?>

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply