Waqas
Waqas

Reputation: 291

AES decryption issue using aes-128-ecb

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

enter image description here

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

Answers (2)

Topaco
Topaco

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

Espen
Espen

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

Related Questions