Some have argued for using AES-256-CTR with HMAC-SHA-256 for authenticated encryption over AEAD-specific modes like EAX and GCM.

However, when doing, this, what should be HMAC'd? And how? Specifically:

  1. Should a key different from the encryption key be used to sign the ciphertexts?
  2. If so, should there be a unique signing key for each unique encryption key?
  3. If so, is it acceptable for the two keys to be stored alongside one other (e.g., as a longer "virtual" key?
  4. Should only the ciphertext (and optional associated data) be HMAC'd?
  5. Should the nonce be part of the HMAC?
  6. Should the encryption key be part of the HMAC (assuming separate encryption and signing keys)?
  7. How should the ciphertext, associated data, and potentially other components of the HMAC be composed with one another? Append? XOR? Nested HMACs?

The MAC is there to detect alteration of the data you are interested in, i.e. the result of the decryption. So you have the following choice:

  • either you compute HMAC over the plaintext data (i.e. before encryption when encrypting, after decryption when decrypting);
  • or you compute the HMAC over the encrypted data itself (i.e. after encryption when encrypting, before decryption when decrypting).

In the second case, you have to include in the HMAC input everything that impacts the decryption process, i.e. not only the encryption result per se, but also the IV which was used for that encryption, and, if the overall protocol supports algorithm agility, you should also input the specification of the encryption algorithm (otherwise, an attacker could alter the header of your message to replace the tag which says "AES-256" with the tag which says "AES-128" and you would unknowingly decrypt with the wrong algorithm).

For security, the second choice (encrypt then MAC) is better; see this question on crypto.SE for details (to sum up, when the MAC is computed over the encrypted data, it cannot leak information about the plaintext data, and since it is verified before attempting decryption, it protects against chosen ciphertext attacks). SSL uses MAC-then-encrypt and it has been the source of a lot of issues (all the "padding oracle attacks" and also the so-called BEAST attack would have been avoided with encrypt-then-MAC).

As for the keys, ideally, the encryption key and the MAC key should be derived from a master key with a PRF. In plain words: hash your master key K with SHA-512; the first half of the result will be the encryption key, the second half will be the key for HMAC.

But, really, you should use EAX or GCM. They do everything correctly and (that's an important point) they have very light requirements on IV selection: they just need a non-repeating IV, hence can use a simple counter, whereas handmade CTR needs non-overlapping IV ranges (an IV with uniform random selection is correct, but randomness is a hard requirement)(and CBC is even worse, it needs unpredictable randomness). The only justification for not using EAX or GCM in a new system (where you are not constrained with backward compatibility) is a possibly non-availability of an EAX or GCM implementation. I would argue that, even in this case, it would be better to retrofit some AES-ECB code into an EAX implementation.

  • Thanks for the detailed answer. I have included support in the project I'm working on GCM, but most of the developers (including myself) use OSX, which comes with a version of OpenSSL that doesn't support GCM (or CTR, unfortunately). So for development, it will use AES-256-CBC with HMAC-SHA-256 (if CTR and GCM aren't supported, otherwise it will use GCM > CTR+HMAC > CBC+HMAC). In production environments it will use GCM. – Stephen Touset Sep 21 '12 at 18:00
  • 1
    Why derive both keys from a single key via a hash? As opposed to, say, generating a larger 512-bit virtual key from a cryptographically random source and splitting it? Is there a practical difference? – Stephen Touset Sep 21 '12 at 18:03
  • A long, randomly generated key is fine. I wanted to show that it was not needed and that the proper way for "sharing" the key between the block cipher and the MAC was to use a PRF. – Thomas Pornin Sep 21 '12 at 18:29
  • 1
    No, not the key. I have been lax; the precise notion is everything that the attacker can modify. By construction, he cannot alter the key. The attacker can modify data in transit, which includes the IV, and (if possible in the protocol) the type of algorithm to use. – Thomas Pornin Sep 21 '12 at 19:53
  • 1
    There is nothing bad with using HMAC alone, and the same key can be reused for multiple messages. Be warned that attackers may try to duplicate, drop or reorder existing messages, so if you send a sequence of messages, each with its own HMAC, then the data which is MACed should include some unambiguous marker (e.g. a sequence number) to detect that kind of alteration. – Thomas Pornin Jul 3 '15 at 18:03

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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