Search code examples
javascriptencryptioncryptographyaescryptojs

How to add HMAC to CryptoJS AES encryption?


CryptoJS's convenience function CryptoJS.AES.encrypt("some plaintext", "password") doesn't seem to do any authentication.

I see CryptoJS provides an HMAC class, but I'm confused about how to use this to encrypt-then-authenticate.

I searched around for tutorials and other questions but couldn't find any.

How would I add authentication using the above CryptoJS HMAC class to authenticate the ciphertext produced by CryptoJS.AES.encrypt?


Solution

  • The idea with the HMAC provided by cryptoJS is to have you, the developer, pass it both the encrypted data and a key in order for it to spit out the MAC on the other end.

    Below is an example of how you could use it to produce a MAC for your encrypted data. The idea here is that the key object is the shared secret used between you and trusted parties to verify the integrity of the encrypted data.

        //Encrypt Data
        var encryptObject = CryptoJS.AES.encrypt(content, key, { iv: yourIV });
    
        //Calculate HMAC
        var HMAC = CryptoJS.HmacSHA256(encryptObject.toString(), key);
    

    A few things to keep in mind.

    • Always calculate the HMAC on the encrypted object before decryption. This prevents any manipulation of the encrypted data to cause harm after decryption.

    • Make sure the data encoding/format is the same when validating the HMAC. For example, above I used the toString() of my encrypted object, I did this becuase cryptoJS automatically serializes that object to only be the ciphertext. Upon decryption, I calculate the HMAC on the binary string of the encrypted blob I am presented with to make sure the HMAC calculates correctly.

    With that I think you should be set to validate some data!

    Also for a working example, you could check out http://meowcrypt.com/ which is my in browser file encryption service for google drive that uses cryptoJS.