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
.
Here is my code to solve problem with migration from PHP to NodeJS. I have strict 32 bytes key so I have to use aes-256-ecb
.
PHP code I want rewrite:
$text = "Some super mega text I want to encode";
$skey = "rcbTw667C7zxghZ5U3gwhQlp22t8c5Rq";
function encode($text,$skey) {
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $skey, $text, MCRYPT_MODE_ECB, $iv);
return base64_encode($crypttext);
}
echo encode($text,$skey);
Output:
dU1eOy+YwkYvm/KCTB8aqR1UsisyrHrvBu+E/H3G/s0aagMDKlNFekGXNQyFMFJD
NodeJS:
var crypto = require('crypto');
var text = "Some super mega text I want encode";
var skey = "rcbTw667C7zxghZ5U3gwhQlp22t8c5Rq";
function encode(text, skey) {
var len = text.length;
var padSize = 16 - ((len + 16 - 1) % 16 + 1);
for (var i = 0; i < padSize; i++) {
text += '\0';
}
var cipher = crypto.createCipheriv('aes-256-ecb', skey, '');
cipher.setAutoPadding(false);
var encrypted = cipher.update(text, 'utf8', 'base64');
encrypted += cipher.final('base64');
return encrypted;
}
console.log(encode(text, skey));
Output:
dU1eOy+YwkYvm/KCTB8aqR1UsisyrHrvBu+E/H3G/s0aagMDKlNFekGXNQyFMFJD
Also NodeJS mcrypt package works:
npm install mcrypt
Code:
var text = "Some super mega text I want encode";
var skey = "rcbTw667C7zxghZ5U3gwhQlp22t8c5Rq";
function encode(text, skey) {
var MCrypt = require('mcrypt').MCrypt;
var rijEcb = new MCrypt('rijndael-128', 'ecb');
rijEcb.open(skey);
var ciphertext = rijEcb.encrypt(text);
return ciphertext.toString('base64');
}
console.log(encode(text, skey));
Output:
dU1eOy+YwkYvm/KCTB8aqR1UsisyrHrvBu+E/H3G/s0aagMDKlNFekGXNQyFMFJD
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With