HMAC in Java
In 2018 AWS CTO(Vogels) said: "Security is everyone's job". For the last 2 years, there was so many famous and big data leaks and breaks that made that statement be very true more than ever. Security often could mean worst performance and worst user experience so in order to get it right you really need to think about the designs before jumping into to code and consider performance and user experience has main requirements. I was thinking about writing about how to do HMAC in Java for a while and recently Redis 6.0.0 come out and to my surprise, there was a refactoring on the password part in order to use HMAC. Security easily could scare engineers often because it is not something well spread yet but I believe this will change soon. It does not matter if you have to deal with PII Data or not, security is super relevant because everybody is running their workloads at the cloud or with IoT and Edge devices which means more distribution, more code, more points of failures, and therefore more attacking vectors. HMAC security depends on the security of the underlying has a function but HMAC is more secure, it will be hard to lunch successful collision attacks on it because of the secret key. So before I talk more about how HMAC works and show the java code let's understand why we would use HMAC.
As you might need to deal with PII(Personal Identifiable) Data like SSN(Social Security Number), Address, Email, Name, Last Name, login credentials, and Passwords. For security reasons, you might need to store data at Rest(Databases) and Data at Transit(TLS / mTLS). So why should I consider HMAC instead of Symmetric or Assimetric keys? Well, there is a couple of reasons, for instance, let's consider passwords, why we should know the plaintext for a password? It does not sound like a good idea for security reasons. Another use case could be cookies. Using HMAC is interesting because as you might need to do key rotations since HMAC is a HASH(there is no way we are getting the original value back) would not make sense to rotation it or to re-generate the hash. HMAC is used in scenarios where you want to check for "Integrity" and "Authenticity". HMAC is also used on IPSec(VPNs), TLS, and Json Web Tokens and Bitcoin(Hashcash).
How HMAC works?
So basically HMAC works this way. There is a Cryptographic Hash Function and Cryptographic Hash Key. The HMAC is associated with a Hash function like SHA-256 or SHA-3 so the HMAC carries the name of the function used like HMAC-SHA-256 or HMAC-SHA-3.
HMAC is a 2 phase computation. First, the secret key is used to derived 2 secret keys(inner and outer keys).
In the first phase, the algorithms produce an internal hash derived from the Message and inner key.
The second phases produce the final HMAC code derived from the inner hash and the outer key. This algorithm provides immunity against Length Extension Attacks. So talking is cheap let's see how we do that in Java.
Java Code
We are using only java standard library here. Basically, there is just one function because once we produce the HMAC there is no turning back. So we need to create a MAC instance saying what algorithm we will be using for our case will be: HMAC-SHA-256. Then we need to instantiate a Secret Key Spec, for educational reasons the key is hardcoded "secreT1_" on line 34, that secret should be a cipher and safely stored in places else like Vault or Secured S3. So after that, we initialize the MAC and we can do the HASH by calling mac.DoFinal. That's pretty much it, as you guys can see is pretty simple.
Cheers,
Diego Pacheco