0

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); 

'''

1
  • What is the result of the decryption? Can you provide a runable example of your problem? Commented Nov 14, 2019 at 7:53

2 Answers 2

3

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!

Sign up to request clarification or add additional context in comments.

Comments

0

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); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.