This question already has an answer here:

I am using HMAC to create a message authentication code. My question is, does it matter if I use cipher text + encryption key or plain text + encryption key? I had a look at a implementation and as far as I can see they just concatenate the values (message and encryption key) and hash them.


marked as duplicate by Ella Rose, yyyyyyy, Community Jun 14 '18 at 20:17

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • $\begingroup$ cipher text + encryption key or plain text + encryption key, are very different, the first is encrypt then MAC, the second is MAC then encrypt and they have different properties. With encrypt then MAC decryption is not attempted until the MAC is verified so less code is run until verification succeeds. $\endgroup$ – zaph Jun 14 '18 at 16:48

There are 3 terms related to MAC use: encrypt-then-mac, mac-then-encrypt, and encrypt-and-mac. The final one doesn't apply to HMAC, it refers to when a single algorithm does both encryption and authentication.

Encrypt-then-mac is in my opinion always preferable for a few reasons:

  1. You can reject forgeries without needing to decrypt them.
  2. If your MAC algorithm leaks information about the message (through side channels) then then the leaked message is only ciphertext which is information that is already "public".
  3. There are fewer "moving parts" to worry about. You do not need to encrypt the mac result. You can use a MAC algorithm that doesn't require a nonce to prevent leaking whether or not someone sends the same message twice. *

If every implementation detail is done perfectly than any of the 3 options can work. For HMAC specfically... 1 is a good reason. 2 may not be a concern for HMAC specifically because there are likely no sidechannels that can't be exploited without physical access or proximity. For 3, I notice you wrote "plaintext + key" not "plaintext + nonce + key". That's an important flaw. HMAC is deterministic so if plaintext1 = plaintext2 then the two message tags will be equal.

The Cryptographic Doom Principle might also be an interesting read.

* But if you're sending the nonce over the network you should include it anyway. And your encryption algorithm should always use a nonce if the same key encrypts multiple messages.


Yes, it does matter. A MAC should always be over the ciphertext, not the plaintext.

HMAC(key, ciphertext) = Hash((DerivedKey xor OuterPad) || Hash((DerivedKey xor InnerPad) || Ciphertext))

Where || denotes concatenation.
OuterPad is a one-hash-block long hexidecimal constant 0x5C5C...5C.
InnerPad is a one-hash-block long hexidecimal constant 0x3636...36.

Of course you should use an existing implementation of HMAC instead of trying to make your own, but if your library is just concatenating values and then hashing them it's not HMAC, and you should use a different library (assuming the library actually calls it HMAC).

There are other MACs than just HMAC, such as SHA-3's KMAC or Poly1305. They also should only be applied to the ciphertext. Your library may be using one of these. I happen to like the libsodium library. It uses Poly1305 for its MAC. It also includes a design that makes it hard to misuse: it's impossible to use a symmetric cipher without properly applying a MAC, so you don't have to worry about the answer to this question. You just call the appropriate crypto_secretbox function!

The following question and answers give reasoning for Encrypt-Then-MAC being optimal: Should we MAC-then-encrypt or encrypt-then-MAC?

  • 1
    $\begingroup$ "A MAC should always be over the ciphertext, not the plaintext" Why? A ;ink to an article that explains those pros/cons would be helpful to make this a more complete answer. $\endgroup$ – Monty Harder Jun 14 '18 at 19:49
  • $\begingroup$ Hi. Thanks for your answer. I looked at the GO implementation: golang.org/src/crypto/hmac/hmac.go?s=1931:1981#L60. You are right, the statement "they just concatenate the values (message and encryption key) and hash them" is incorrect. They do that as well but it's not the only thing they do. Like @MontyHarder I am interested in the "why". $\endgroup$ – pesdfa Jun 14 '18 at 20:10
  • $\begingroup$ Linked a good answer for why encrypt-then-MAC is optimal. $\endgroup$ – SAI Peregrinus Jun 15 '18 at 14:46

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