Trying to recreate the following php encryption code in node.js:
$size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($size, MCRYPT_RAND);
$msg = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, 'MY_KEY_LONG_STRING', 'PLAINTEXT', MCRYPT_MODE_ECB, $iv));
Tried this:
var text = 'PLAINTEXT';
var len = text.length;
for (var i = 0; i < 16 - len % 16; i++) { // pad to multiple of block size
text += '\0';
}
var key = 'MY_KEY_LONG_STRING';
key = key.substr(0, 16); // trim to expected key size for aes128
var cipher = crypto.createCipher('aes-128-ecb', key);
cipher.setAutoPadding(false); // did our own padding, to match mcrypt_encrypt
var encrypted = cipher.update(text, 'utf8', 'base64');
encrypted += cipher.final('base64');
Getting different result from the php one...
Also tried creating cipher with IV (which shouldn't even be used in aes-128-ecb):
var cipher = crypto.createCipheriv('aes-128-ecb', key, '');
Also, different result from php. Any ideas how to make this behave exactly like the php version?
Playing two rather ill constructed libraries against each other can be fun. Rather than doing all the work, I'll help you along with ideas as requested:
aes-192-ecb
as algorithm (you need to keep using MCRYPT_RIJNDAEL_128
but substitute, that 128 in PHP is the block size not the key size)createCipher
as the second argument is the password; node.js performs key derivation if you use that one, so you need to use the three argument createCipher
instead and supply any 16 byte IVThe IV code in PHP only taxes the random number generator needlessly, the IV is not used.
Code to do the padding
var padSize = 16 - ((len + 16 - 1) % 16 + 1);
for (var i = 0; i < padSize; i++) { // pad 0 .. 15 until to multiple of block size
text += '\0';
}
Or you could use your own padding method (in the question) unless len % 16 == 0
.