I am trying to encrypt data using crypto-js javascript library and trying to decrypt the same encrypted text on nodejs side using node crypto library. I am using AES 256 encryption algo with CTR mode with no padding. I am able to encrypt properly but the description on nodejs crypto module is not producing same plain text.
If I try to encrypt or decrypt using the same crypto-js and node crypto library, it works fine but encryption on crypto-js and description on crypto is not working as expected. I have tried to confirm if I encrypt and decrypt in the same library than it works or not and it works perfectly fine. Can someone please check what mistake I am making here?
Please find below code samples.
Encryption:
var key = CryptoJS.enc.Hex.parse('F29BA22B55F9B229CC9C250E11FD4384');
var iv = CryptoJS.enc.Hex.parse('C160C947CD9FC273');
function encrypt(plainText) {
return CryptoJS.AES.encrypt(
plainText,
key,
{
iv: iv,
padding: CryptoJS.pad.NoPadding,
mode: CryptoJS.mode.CTR
}
);
}
Descryption using NodeJS crypo module:
var algorithm = 'aes-256-ctr';
var key = 'F29BA22B55F9B229CC9C250E11FD4384';
var iv = 'C160C947CD9FC273';
var outputEncoding = 'hex';
var inputEncoding = 'hex';
const decipher = crypto.createDecipheriv(algorithm, key, iv);
let decrypted = decipher.update('8df5e11f521cf492437a95', inputEncoding, 'utf8');
decrypted += decipher.final('utf8');
console.log(decrypted);
As I have mentioned above, I have JavaScript crypo-js and NodeJS crypo module sessions working fine if I encrypt and decrypt using the same lib but doesn't work otherwise. Please check the working code as below.
JavaScript: http://jsfiddle.net/usr_r/2qwt8jsh/2/
In contrast to the NodeJS-code (Crypto
), the JavaScript-code (CryptoJS
) interprets keys and IV as hexadecimal strings. Therefore, in the JavaScript-Code AES-128 is used and in the NodeJS-Code AES-256. To solve the problem, both codes must use the same encryption.
Option 1: Change the JavaScript-code to AES-256: Replace in the JavaScript-code
var key = CryptoJS.enc.Hex.parse('F18AB33A57F9B229CC9C250D00FC3273');
var iv = CryptoJS.enc.Hex.parse('D959B836CD9FB162');
by
var key = CryptoJS.enc.Utf8.parse('F18AB33A57F9B229CC9C250D00FC3273');
var iv = CryptoJS.enc.Utf8.parse('D959B836CD9FB162');
Option 2: Change the NodeJS-code to AES-128: Replace in the NodeJS-code
var algorithm = 'aes-256-ctr';
var key = 'F18AB33A57F9B229CC9C250D00FC3273';
var iv = 'D959B836CD9FB162';
by
var algorithm = 'aes-128-ctr';
var key = Buffer.from('F18AB33A57F9B229CC9C250D00FC3273', 'hex');
var iv = Buffer.from('D959B836CD9FB1620000000000000000', 'hex');
With one of each of the two changes, the codes of both links produce the same result.
If AES-256 should be used and key and IV should be specified as hexadecimal strings, a correspondingly large key and IV must be used, e.g. on the JavaScript-side:
var key = CryptoJS.enc.Hex.parse('F18AB33A57F9B229CC9C250D00FC3273F18AB33A57F9B229CC9C250D00FC3273');
var iv = CryptoJS.enc.Hex.parse('D959B836CD9FB16200000000000000');
and on the NodeJS-side:
var algorithm = 'aes-256-ctr';
var key = Buffer.from('F18AB33A57F9B229CC9C250D00FC3273F18AB33A57F9B229CC9C250D00FC3273', 'hex');
var iv = Buffer.from('D959B836CD9FB1620000000000000000', 'hex');