How to format data to correctly decrypt hex strings in CryptoJS

49
November 26, 2020, at 06:30 AM

I have a TCP server that is receiving information via direct IP. I am receiving this information encrypted in AES-128-CBC.(hex byte buffer) I then turn the buffer into a string of hex bytes with no spaces. "originalMsg"

I get passed the IV, the encrypted message, and I have the key hardcoded. I still can't get the message to decrypt correctly. I will usually get a completely different decryption or an empty string. I am assuming one or more of my variables is in the wrong format?

I have zero experience with cryptology before this week but this is my task. So, I apologize if the problem is something miniscule.

I am receiving the data from my colleague from C language. I have a fear that CryptoJS isn't compatible with the data I am being passed? Any help is much appreciated.

code.js

const CryptoJS = require("crypto-js");
var originalMsg = "5303F15FB8317A010300000000000001F3E0C003E24340E4E4"
var encrypted = "00000003C4302B119E7BB9C36655F6BCDF251808C6748A11949A89309AD17600F6164FF45CDC"
var key = "242E389B1672B4ECEA92FE7466DF3A52"
var iv = "0000E34500FF0000000000FF00000000"

var decryptData2 = function(encryptedData) {
    var C = CryptoJS;                          
    var Key = CryptoJS.enc.Hex.parse("242E389B1672B4ECEA92FE7466DF3A52")
    var IV = CryptoJS.enc.Hex.parse("0000E34500FF0000000000FF00000000")
// I have tried 
    var decryptedText = C.AES.decrypt(encryptedData, Key, {               
        iv: IV,
        mode: C.mode.CBC,
        padding: C.pad.Pkcs7
    });
   
    return decryptedText.toString(CryptoJS.enc.Utf8);
}
var result = decryptData2(CryptoJS.enc.Hex.parse("00000003C4302B119E7BB9C36655F6BCDF251808C6748A11949A89309AD17600F6164FF45CDC"))
console.log(result); 

Edit: Updated iv and encrypted variables

//old vars
encrypted ="00000003C4302B119E7BB9C36655F6BCDF251808C6748A11949A89309AD17600F6164FF45CDC"
iv = "02C4100000E34500FF0000000000FF00"

Answer 1

It's always good to rely on sample data because that helps a lot in finding a working solution. Below you find a sample program that is been able to decrypt the message.

Some remarks how it works:

a) I'm converting all given data to Crypto-JS word arrays to be compatible with the cryptography methods:

var key = CryptoJS.enc.Hex.parse("242E389B1672B4ECEA92FE7466DF3A52");

b) to see what encrypted data I should use for decryption I'm first encrypting the originalMsg and get this output:

ciphertext:             2b119e7bb9c36655f6bcdf251808c6748a11949a89309ad17600f6164ff45cdc
c.txt exp:  00000003c4302b119e7bb9c36655f6bcdf251808c6748a11949a89309ad17600f6164ff45cdc

The first line is the encrypted "originalMsg", the second line is the data you identified as "encrypted" - see the difference ? As I earlier commented the encrypted value is 6 bytes too long (it has to be multiples of 16, your "encrypted" is 38 bytes long).

c) trying to decrypt needs an input in base64 encoding (there are other ways, this way is the most convenient way for me to use it here) so first I'm encoding the word array "encrypted" to (Base64 encoded) "encryptedBase64" and present the string to the aesCbcDecrypt function. As the data is too long there is no output.

var encryptedBase64 = CryptoJS.enc.Base64.stringify(encrypted);
var decrypted = aesCbcDecrypt(key, iv, encryptedBase64);
console.log("decrypted: " + decrypted);
result:
decrypted:

d) now I'm cutting off the first 6 bytes (12 hex "characters") from encrypted and use the remaining data for the same decryption function:

var encrypted2 = CryptoJS.enc.Hex.parse("2B119E7BB9C36655F6BCDF251808C6748A11949A89309AD17600F6164FF45CDC");
console.log("encrypted2 length: " + encrypted2.sigBytes);
var encrypted2Base64 = CryptoJS.enc.Base64.stringify(encrypted2);
var decrypted2 = aesCbcDecrypt(key, iv, encrypted2Base64);
console.log("decrypted2: " + decrypted2);
console.log("orig.Msg  : " + originalMsgHex);
result:
decrypted2: 5303f15fb8317a010300000000000001f3e0c003e24340e4e4
orig.Msg  : 5303F15FB8317A010300000000000001F3E0C003E24340E4E4

The decrypted2 value is now equal to the originalMsg.

If you like to see the code running in an online compiler - here is the link: https://repl.it/@javacrypto/SoCryptoJsDecrypt#index.js

I leave it up to you to put this information together to get a programmatically solution as this should only explain how to get the dercrypted data.

complete output:

key length: 16
iv length: 16
ciphertext:             2b119e7bb9c36655f6bcdf251808c6748a11949a89309ad17600f6164ff45cdc
c.txt exp:  00000003c4302b119e7bb9c36655f6bcdf251808c6748a11949a89309ad17600f6164ff45cdc
encrypted length: 38
decrypted:
encrypted2 length: 32
decrypted2: 5303f15fb8317a010300000000000001f3e0c003e24340e4e4
orig.Msg  : 5303F15FB8317A010300000000000001F3E0C003E24340E4E4

Security warning: the code does have no exception handling and is for educational purpose only.

complete code:

const CryptoJS = require("crypto-js");
var originalMsgHex = "5303F15FB8317A010300000000000001F3E0C003E24340E4E4";
var originalMsg = CryptoJS.enc.Hex.parse(originalMsgHex);//("5303F15FB8317A010300000000000001F3E0C003E24340E4E4");
var encrypted = CryptoJS.enc.Hex.parse("00000003C4302B119E7BB9C36655F6BCDF251808C6748A11949A89309AD17600F6164FF45CDC");
var key = CryptoJS.enc.Hex.parse("242E389B1672B4ECEA92FE7466DF3A52");
var iv = CryptoJS.enc.Hex.parse("0000E34500FF0000000000FF00000000");
console.log("key length: " + key.sigBytes);
console.log("iv length: " + iv.sigBytes);
// encryption of originalMsg
var ciphertext = aesCbcEncrypt(key, iv, originalMsg);
console.log("ciphertext:             " + ciphertext);
console.log("c.txt exp:  " + encrypted);
// decryption of encryption fails due to wrong length (not multiple of 16)
console.log("encrypted length: " + encrypted.sigBytes); // result: 38
// prepare encrypted for decryption by base64encoding
var encryptedBase64 = CryptoJS.enc.Base64.stringify(encrypted);
var decrypted = aesCbcDecrypt(key, iv, encryptedBase64);
console.log("decrypted: " + decrypted);
// cutting off the first 6 bytes from encrypted
var encrypted2 = CryptoJS.enc.Hex.parse("2B119E7BB9C36655F6BCDF251808C6748A11949A89309AD17600F6164FF45CDC");
console.log("encrypted2 length: " + encrypted2.sigBytes);
var encrypted2Base64 = CryptoJS.enc.Base64.stringify(encrypted2);
var decrypted2 = aesCbcDecrypt(key, iv, encrypted2Base64);
console.log("decrypted2: " + decrypted2);
console.log("orig.Msg  : " + originalMsgHex);
function aesCbcEncrypt(keyF, ivF, data) {
  const cipher = CryptoJS.AES.encrypt(data, keyF,
  {
    iv: ivF,
    padding: CryptoJS.pad.Pkcs7,
    mode: CryptoJS.mode.CBC
  });
  return cipher.ciphertext;
}
function aesCbcDecrypt(keyF, ivF, ciphertext) {
  const cipher = CryptoJS.AES.decrypt(ciphertext, keyF,
  {
    iv: ivF,
    padding: CryptoJS.pad.Pkcs7,
    mode: CryptoJS.mode.CBC
  });
  return cipher;
}
READ ALSO
How cancel Timeout inside object

How cancel Timeout inside object

I have the following code:

32
Google Drive API can not upload file into specific folder

Google Drive API can not upload file into specific folder

I have a unlimited storage google drive account from my school account, so I shared drive with my main google account, I want to use apis of google drive to upload video to that shared drive by an file input formThis is where i want to store the file:

27
How to insert json object inside nested object in a document based on nested object UUID

How to insert json object inside nested object in a document based on nested object UUID

I am working on a small project and I am stuck from last month and looking for an exact query to update my document at the exact location

30
Trying to return from co generator runner in nodejs

Trying to return from co generator runner in nodejs

I want to create a function that runs asynchronous code sequentialyThis function takes parameters and returns a Promise that resolves with a JavaScript object

52