Robbert Robbert - 8 months ago 47
Javascript Question

Javascript AES Encryption returning too many characters

I am trying to implement a PHP encryption script into JavaScript. My PHP script returns a 128 character string, while my Javascript based one returns 160 characters. The first 128 characters of the JavaScript based version match the PHP based version.

function pkcs5_pad ($text, $blocksize){
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
$skey = "somekey";
$ivKey = "someIVKey";
$input = "empid=xxxxxx;timestamp=Sat, 19 Nov 2016 00:33:03 UTC";

try {
$size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128,'cbc');
echo strlen($input) . "\n";
$input = pkcs5_pad($input, $size);
echo strlen($input) . "\n";
$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');

$key = pack('H*', $skey);
$iv = pack('H*', $ivKey);
# The key size used is 16, 24 or 32 bytes - for AES-128, 192 and 256 respectively

if (mcrypt_generic_init($cipher, $key, $iv) != -1){
$encrypted = mcrypt_generic($cipher, $input);
$encryptedString = bin2hex($encrypted);
echo $encryptedString . "\n";
echo strlen($encryptedString) . "\n";
} catch (Exception $ex) {
echo $ex->getMessage();

The length
here gives me 128 characters.

My JavaScript based version uses CryptoJS to create looks like this

var aesKey = "somekey";
var ivKey = "someIVKey";

function pkcs5_pad (text, blocksize){
var pad = blocksize - (text.length % blocksize);
console.log("pad:" + pad);
return text + str_repeat(chr(pad), pad);

input = "empid=xxxxxx;timestamp=Sat, 19 Nov 2016 00:33:03 UTC";

var size = 16;
var input = pkcs5_pad(input, size);
console.log('"' + input + '"');

var key = CryptoJS.enc.Hex.parse(aesKey);
var iv = CryptoJS.enc.Hex.parse(aesIV);

var encryptedString = CryptoJS.AES.encrypt(input,key,{iv: iv});
encryptedString = encryptedString.ciphertext.toString();

Everything matches, including the string lenght before and after pkcs5_pad. I'm using some additional JavaScript code from to call str_repeat, and chr. Here
returns 160 characters and the first 128 match that of my PHP script.

My understanding is that version 3 of CryptoJS uses CBC mode, but I've also set the mode explicitly to CBC to no avail. I've also returned the encrypted string as hex

encryptedString = encryptedString.ciphertext.toString(CryptoJS.enc.Hex);

Where am I going wrong?

The output of the PHP version is


The output of the JavaScript version is


Answer Source

The extra 32 characters are hex encoding of 16 bytes and that is the padding. The Java is adding padding, the PHP is not.

Note that mcrypt does not use standard PKCS#7 (née PKCS#5) padding.

Good encryption libraries will have a padding option and add the padding on encryption and remove it on decryption. You should not have to do your own padding.