Search code examples
node.jsencryptioncryptojs

CryptoJS with hex key not decrypting properly


I have a dataset that was encrypted that I'm trying to decrypt with CryptoJS. I've tried various combination of things but for some reason the result is not what I'm expecting. I have provided the key below and also the text I want to decrypt. What I'm expecting at msg1 is 32 characters long but I keep getting 48. Its as of its padding it with an extra 16 characters.

Thanks in advance for the help.

key = 'd13484fc2f28fd0426ffd201bbd2fe6ac213542d28a7ca421f17adc0cf234381';
text = '8bf3955488af91feb7bd87220910cee0';


decrypt(text: string): void{

       let msg1 = CryptoJS.AES.decrypt(text, CryptoJS.enc.Hex.parse(key), { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding});
       msg1 = CryptoJS.enc.Hex.stringify(msg1 );

}

Solution

  • Solving it is pretty simple, but reading the docs and the code, I'm not quite clear why.

    This is clearly wrong:

    let msg1 = CryptoJS.AES.decrypt(text, CryptoJS.enc.Hex.parse(key), { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding});
    

    Given your description, you are expecting the byte sequence represented by the hex digits "8bf3955488af91feb7bd87220910cee0" to be the body. But that's not what your passing. You're passing the characters. So when it decrypts it, the first byte is the ASCII value of 8 (0x38), not 0x8b. Given that, you should be parsing the hex like this:

    let msg1 = CryptoJS.AES.decrypt(CryptoJS.enc.Hex.parse(text), ...
    

    But, for reasons I'm having trouble understanding, that doesn't work. decrypt expects Base64 (or at least it will accept Base64). I can't find any documentation that says this, and the code creates the decrypt function magically in a way that I don't fully understand, and this is why I really hate doing crypto work in JavaScript.

    That's out of my system now, so let's get to the answer:

    cipher = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Hex.parse(text))
    
    let msg1 = CryptoJS.AES.decrypt(cipher, CryptoJS.enc.Hex.parse(key), { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding});
    

    And that should give you the result you're expecting.