Cryptography Stack Exchange is a question and answer site for software developers, mathematicians and others interested in cryptography. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

What is best to use (for message integrity) between…

  1. AES(Data) + HMAC(Data)
  2. AES(Data + HMAC(Data))
  3. AES(Data + Hash(Data))

…and why?

share|improve this question
@user2908183 Good discussion here... – hunter Nov 1 '13 at 21:58
@RickyDemer - on second thought - I see your point - I'm removing my initial comments. – hunter Nov 1 '13 at 22:08

"Encrypted hash" totally fails if the encryption uses a malleable mode like CTR. CTR runs AES in a stream-cipher-like mode where the data to encrypt is simply XORed with a key-dependent stream, so the attacker can flip bits with extreme precision; so if the attacker guesses the contents, he can modify them and fix the hash easily.

More generally, if you want a MAC then use a MAC. The "encrypted hash" is just a homemade attempt at a MAC algorithm, and we know that homemade algorithms are rarely strong, and even when they are we cannot make sure that they really are strong.

As for how to combine encryption and a MAC, this is a well-known questions for which a lot of theory and practice has been accumulated; see this question. To sum it up: you want to compute the MAC over the encrypted data, because it avoids any issue with the MAC algorithm leaking information on the processed data, and it protects the decryption implementation from malformed data.

Now, HMAC seems to be reasonably well-behaved and not to leak information about the data on which it is applied. Your setups 1 and 2 are what is used by, respectively, SSH and SSL/TLS. In neither case did it prove fatal; however, the lack of protection on the encrypted format allowed various padding oracle attacks to experience some success on implementations which were not sufficiently careful when decrypting malformed input data.

share|improve this answer
OK... How much long should the hmac key be for SAH1 and SHA256 respectly? Using a key for received messages (client_read_hmac_key) and another key for sent messages (client_write_hmac_key) should allow me to use the same AES key for both sending and receiving because using two different keys for HMAC mitigates the replay attack of a client command to the server. Am I right? – user2908183 Nov 2 '13 at 15:00
PS: AES will work in CBC mode... – user2908183 Nov 2 '13 at 15:08
A key for HMAC should be large enough to prevent brute force, and needs not be longer than that. So, 128 bits. On a general basis, you all keys should be distinct, so you would need four keys (one for HMAC and one for encryption, in each direction). Knowing whether some keys can be shared is tricky. The usual setup is that, from a master key, a "key block" is derived with a Key Derivation Function, which is split into all needed keys. See SSL/TLS for an example. – Thomas Pornin Nov 2 '13 at 16:19
Also, I must add that you seem to be in the process of designing your own protocol, with the help of a Q&A Web site where random strangers give their opinion. This path usually leads to sorrow. You really should try to use existing protocols and implementations where hard details have been ironed out (i.e. SSL, OpenPGP...). – Thomas Pornin Nov 2 '13 at 16:24
I definitely have to develop my own protocol because of some particular needs... So what is best to use? AES(Data) + HMAC(AES(Data)) or AES(Data + HMAC(AES(Data))) ? Thanks – user2908183 Nov 10 '13 at 16:58

2, because the only issue is that there might be a feasible way to have a non-negligible
probability of producing a new AES ciphertext that decrypts to already-encrypted data.

(Of course, as pointed to by hunter, AES(data) + HMAC(AES(data)) is even better.)

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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