An HMAC function is designed to verify message integrity, i.e., that the message has not been tampered with. It is generally (always?) implemented by using a hashing function H, and calculating the hash H(key + H(key + message)), where + signifies concatentation (Source). The key is secret, and is reused for multiple HMAC calculations.

A related cryptographic technique is "salting." This is commonly used when storing passwords: each password will have a unique salt (or "nonce"), and you store the hash H(salt + key) and the salt together in the database. The salt is not encrypted, is not reused for other passwords, and is not a "secret" like the HMAC key.

My question is: does it add any security to add a random salt to the message you are validating with HMAC?

In my situation, the "message" I am validating is a six digit number. My "gut" was to use a salt (perform HMAC on salt + my six digit number) to protect against rainbow tables, but then it occurred to me that, since I'm using a 512-bit HMAC key generated by a cryptographically secure random number generator, there may be no added security. If I'm understanding it correctly, this answer (to a question about HMACing short inputs) means that there is no added security.

However, I am not completely certain. So, can someone clarify? Is there any value in adding a salt to your message prior to determining the HMAC?

  • $\begingroup$ Technically HMAC is $H(K \oplus opad || H(K \oplus ipad || M))$. And yes, it's always that way, though there are other MACs that aren't. $\endgroup$ – otus Jul 8 '14 at 19:59
  • $\begingroup$ I realize the HMAC definition I cited is missing the key padding. Sorry about that. Let's just pretend that, in this example, we're using a key that is exactly the length required :-) $\endgroup$ – Josh Jul 9 '14 at 11:18
  • $\begingroup$ Even in that case the inner and outer keys are different, because the pads are XORed into the key. However, it doesn't matter for this question, so we can just say HMAC and assume it's correctly implemented. $\endgroup$ – otus Jul 9 '14 at 11:21
  • $\begingroup$ I didn't realize the ⊕ symbol meant XOR; thank you for mentioning that. $\endgroup$ – Josh Jul 9 '14 at 17:25

My question is: does it add any security to add a random salt to the message you are validating with HMAC?

This depends on what the HMAC is used for.

If you use a key to sign more than one secret message, a salt will prevent an attacker from knowing whether two of them are equal. (Or brute forcing a message if the key is revealed...)

It is more common that you send the message and its HMAC value through the same channel, in which case protecting the secrecy of what is authenticated does not matter (unless you encrypt and use encrypt-and-MAC). What may matter, however, is that an attacker could do replay attacks, reusing a previous message and HMAC pair.

To protect against replay attacks you need to add not just a salt, but one that the receiver can verify has never been used before. For example, an incrementing counter (that both parties store and compare), a close enough (monotonic) timestamp, or a salt that the receiver chooses e.g. randomly.

  • $\begingroup$ So, just to be sure I understand: there is no added security when 1) the message is not secret, and 2) you are not using encrypt-and-MAC. $\endgroup$ – Josh Jul 9 '14 at 11:21
  • $\begingroup$ Also, in my case I am already protecting against replay attacks because the six digit number being passed in can be used only once to perform a particular action, then it is marked as "used" and subsequent requests with that same ID will simply return "already processed" with no action taken. $\endgroup$ – Josh Jul 9 '14 at 11:21
  • 1
    $\begingroup$ @Josh: Correct. If messages are known to be unique and only allowed once, a salt makes no difference. $\endgroup$ – otus Jul 9 '14 at 11:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.