0

I have these two code snippets. The first one uses createCipher from node:crypto and the second one is supposed to generate the same result using CryptoJS:

const dataText = 'Hello';

const crypto = require('node:crypto');
const c = crypto.createCipher( 'aes-128-ecb', '2C8E29E736CB9514DD93C4D111244990' );
const r = c.update( dataText, 'utf-8', 'hex' ) + c.final( 'hex' );
console.log(r);

const CryptoJS = require('crypto-js');
const encrypted = CryptoJS.AES.encrypt(dataText, '2C8E29E736CB9514DD93C4D111244990', {
  mode: CryptoJS.mode.ECB,
  padding: CryptoJS.pad.Pkcs7
}).ciphertext.toString(CryptoJS.enc.Hex);
console.log(encrypted);

The output should be the same but I get different results:

8a78f5302082a5e59aa5d28a1453cba1
f1b3424bb507a6e6185c1cf91527634d

How should I modify the second snippet to get a match with the first one?

bjornd
  • 22,397
  • 4
  • 57
  • 73

1 Answers1

0

The modification required here is the parsing of the key string into a CryptoJS WordArray using CryptoJS.enc.Hex.parse().

const key = CryptoJS.enc.Hex.parse('2C8E29E736CB9514DD93C4D111244990');

This ensures that the key is correctly interpreted by CryptoJS. Also, we need similar step for node:crypto key setup. Following code is updated with required changes:

const dataText = 'Hello';

const crypto = require('node:crypto');
const ky = Buffer.from('2C8E29E736CB9514DD93C4D111244990', 'hex');
const c = crypto.createCipheriv('aes-128-ecb', ky, null);
const r = c.update(dataText, 'utf-8', 'hex') + c.final('hex');

console.log(r);

const CryptoJS = require('crypto-js');
const key = CryptoJS.enc.Hex.parse('2C8E29E736CB9514DD93C4D111244990');

const encrypted = CryptoJS.AES.encrypt(dataText, key, {
  mode: CryptoJS.mode.ECB,
  padding: CryptoJS.pad.Pkcs7
});
const encryptedHex = encrypted.ciphertext.toString(CryptoJS.enc.Hex);
console.log(encryptedHex);

The output is as follows:

3af672a3f06d44af6bd00f3fa3b2b233
3af672a3f06d44af6bd00f3fa3b2b233
nitishagar
  • 9,038
  • 3
  • 28
  • 40
  • Thank you, there was another catch, but I can get identical results now. I have to reimplement createCipher, not createCipheriv for compatibility reasons. In order to achieve that I had to use evp_bytestokey package to first prepare the key as it's done by createCipher. – bjornd Jul 08 '23 at 12:07
  • 1
    @bjornd - CryptoJS already implements `EVP_BytesToKey()`. However, by default, a salt is used, in contrast to `crypto.createCipher()`. For compatibility with `crypto.createCipher()`, this default behavior simply needs to be changed so that no salt is used. So importing an additional package like `evp_bytestokey` is actually not necessary. – Topaco Jul 08 '23 at 15:26