Reputation: 291
I'm trying to decrypt some data using aes-128-cbc using node.js. When I do same decryption using an online tool it works fine but somehow my node.js code has some bug which I'm unable to pinpoint , the result of decryption is not valid.
Below is working screenshot from an online tool . It works fine
Here is my code which has some issue
'''
var encData = '2WSGjqFJJ0Zxl7Ao6uT9+CpESHBPz+ejTlzPN+ELPtdFbL2cr3hJo/NM2XJXt1UKefdyJFjPxz//suRHM7PyorNtoVAoP8hdbcUndUtFEOpUihzVcllffRI3aoQ57iD5+5NZQEAncDwY/+fve/ocOCgBGJMRGN6CvjSJ9dIKFD2L0u452oBoMFBdkdNEslFabXFTxBut95BO1H+itJjOFCb9pQh0mK9HetzmUMjX7PZ55LysZRvddAracs7Fj3Jc';
var buf = Buffer.from(encData);
var encDataBase64 = buf.toString('base64');
var key = '6bhgdu99954paut6'; //dummy key for stackoverflow question
var mykeydec = crypto.createDecipher('aes-128-ecb', key);
mykeydec.setAutoPadding(false);
var mystrdec = mykeydec.update(encDataBase64, 'base64', 'ascii');
mystrdec += mykeydec.final("ascii"); //?
console.log("dec data", mystrdec);
'''
Upvotes: 0
Views: 1433
Reputation: 49460
The NodeJS-code has several issues: First, createDecipher
is used instead of createDecipheriv
. createDecipher
(meanwhile deprecated by the way) interprets the 2nd parameter as passphrase and generates a key from it, while CreateDecipheriv
interprets the 2nd parameter directly as key.
Second, when creating the buffer buf
, an encoding must be used (here base64
). However, this step can be omitted since the update
-method can also process a string (here the second parameter specifies the input-encoding).
Finally, PKCS7-padding was used to encrypt the data, which is the default padding, so it must not be disabled for decryption.
With the following changes the ciphertext can be decrypted:
var crypto = require('crypto');
var encData = '2WSGjqFJJ0Zxl7Ao6uT9+CpESHBPz+ejTlzPN+ELPtdFbL2cr3hJo/NM2XJXt1UKefdyJFjPxz//suRHM7PyorNtoVAoP8hdbcUndUtFEOpUihzVcllffRI3aoQ57iD5+5NZQEAncDwY/+fve/ocOCgBGJMRGN6CvjSJ9dIKFD2L0u452oBoMFBdkdNEslFabXFTxBut95BO1H+itJjOFCb9pQh0mK9HetzmUMjX7PZ55LysZRvddAracs7Fj3Jc';
//var buf = Buffer.from(encData);
//var encDataBase64 = buf.toString('base64');
var key = '<your obfuscated secret key>';
//var mykeydec = crypto.createDecipher('aes-128-ecb', key); // Use createDecipheriv
var mykeydec = crypto.createDecipheriv('aes-128-ecb', key, null);
//mykeydec.setAutoPadding(false); // Don't disable PKCS7-Padding
//var mystrdec = mykeydec.update(encDataBase64, 'base64', 'ascii'); // Decrypt the Base64-encoded ciphertext directly
var mystrdec = mykeydec.update(encData, 'base64', 'ascii');
mystrdec += mykeydec.final("ascii");
console.log("dec data", mystrdec);
In addition: You have revealed so much information in your question that I was able to find your obfuscated key in a few minutes, which is why I was able to decrypt your ciphertext and hence verify my code changes. In other words, this key is compromised and must not be used anymore!
Upvotes: 3
Reputation: 2576
I am unsure what your exact issue is. It could be a lot of things. How is the data encrypted? Is the length of the string a multiple of the block size?
It could be that padding is needed if that is not the case.
In this example, it all works fine:
const crypto = require("crypto");
//Encrypt
const data = "{\"msg\":\"This data should be protected at all cost! But it is pretty long, so you need to use all chunks...\"}";
const key = "SecretKeyOfExactlyAndOnly32Bytes";
const chunks = [];
const encoder = crypto.createCipher("aes-128-ecb", Buffer.from(key));
encoder.setAutoPadding(true); // This does not match the block size, so padding is needed...
chunks.push(encoder.update(data).toString("base64"));
chunks.push(encoder.final().toString("base64"));
let cipherText = chunks.join("");
console.log("\nCiphertext: ", cipherText,"\n");
//Decrypt
let decoder = crypto.createDecipher("aes-128-ecb", key);
decoder.setAutoPadding(true); // setting this to false yields garbage data on the end because of padding...
let clearText = decoder.update(cipherText, "base64", "ascii");
clearText += decoder.final().toString("ascii");
console.log("\nClear Text: ", clearText);
//Verify Valid JSON
console.log(JSON.parse(clearText).msg);
Upvotes: 0