HMAC on the other hand uses the more complicated construction $ \mathrm{Hash}((\mathrm{key} ⊕ \mathrm{opad}) ∥ \mathrm{Hash}((\mathrm{key} ⊕ \mathrm{ipad}) ∥ \mathrm{message})) $. I assume the more complicated construction of HMAC is required for some security proof, but I don't immediately see why.

For SHA-3 candidates, Hash(key||message) is claimed to be secure, since they're resistant to length extensions, without consuming the key twice. I believe Skein even has some security proof for a very similar mode.

3 Answers
3

You're missing the most important strength of HMAC: it comes with a proof of security (under some plausible assumptions). The outer key plays an important role in the proofs. The best place to learn more is to read the HMAC papers:

In particular, it is very important for their proof that the outer function be keyed. In your scheme, the outer function is not keyed, so their proof of security will not apply.

As they explain in the paper, the role of the inner function is to provide collision-resistance (to compress a long message down to a short fingerprint, in a way so that someone who does not know the key cannot find a pair of messages with the same fingerprint), and the role of the outer function is to act as a message authentication code on this fingerprint. Their security proofs show that if the inner and outer functions each correctly implement their roles, then the combination (HMAC) will be a secure message authentication code. Because the outer function needs to be a secure message authentication code, that means the outer function needs to be keyed for their proof methodology to apply.

Read the papers. They are surprisingly readable, for a theoretical piece of work.

The strange part for me is that HMAC requires this key, but SHA-3 candidates used as MAC don't. I believe Skein has a security proof for a mode that's similar to H(k||m). "We prove that if Threefish is a tweakable PRP (pseudorandom permutation) then Skein is a PRF."
–
CodesInChaosJul 30 '12 at 6:44

1

The explanation is that SHA-3 candidates are designed with "random-oracle-ness" in mind. $\hspace{0.75 in}$
–
Ricky DemerJul 30 '12 at 7:50

1

This newer referenceNew Proofs for NMAC and HMAC: Security without Collision-Resistance (M. Bellare, Crypto 2006) gives an argument that HMAC is secure even if the compression function in the underlying hash has properties insufficient to make the hash collision-resistant. Independently: I like this intuitive argument that the outer hash kind of re-enciphers the result of the previous one; much like adding rounds in a block cipher, that makes recovering the key or otherwise distinguishing results from random much harder.
–
fgrieuMar 18 '14 at 13:02

As a Skein co-author, one of the properties of the UBI chaining mode is to give you HMAC-like properties in one pass. Skein itself consists of the Threefish tweakable block cipher, the UBI chaining mode, and some proofs that extend tweakable block cipher theory into a tweakable hash function theory that reduces the security of the hash function to the security of the block cipher. (I will note in passing that one of the strengths of the Skein team is that we all have certain strengths that we brought to parts of the whole; Mihir took the lead on the proofs, and he's a co-author of HMAC.)

One of the features of that is that you get a one-pass MAC for free with Skein.

HMAC, in contrast is a wrapper around any hash functions that (often) amplifies its security. In the Introduction of the CryptoBytes article on HMAC, they say,

"One of the many difficulties [of constructing a MAC from a hash
function, as opposed to a cipher] is that they are not even keyed
primitives, i.e. do not accommodate naturally the notion of a secret
key." Several constructions were proposed prior to HMAC, but they
lacked a convincing security analysis.

HMAC creates a wrapper that goes around an arbitrary hash function and gives you some security properties that the hash function did not have. Skein designs a tweakable hash function, and it is that tweak that gives you a mechanism to put in a key securely.

I'm putting another answer in because as good as D.W.'s answer is (I up-voted it), it doesn't really answer your question.

You said:

But the simple construction Hash(Hash(key|message)) would offer those properties too.

But the construction you gave -- Hash(Hash(key|message)) -- has a weakness that HMAC does not.

One of those properties was resistance to simple collisions. What is a "simple" collision is undefined, and you might not consider what I'm going to say to be a simple collision, but it is nonetheless a weakness.

If I can construct a collision to key|message then that collision propagates out to the MAC as a whole. But the same attack does not work against HMAC.

HMAC, as you know, uses two keys. I'm going to call them K1 and K2, and they're constructed by XORing with the two different pads. Think of it as a simple key derivation function. HMAC gets added strength not only because it uses an inner key and an outer key, but that they are different keys. Consequently, an attacker who constructs an attack based upon a hash collision must collide against each of these keys, which is hard. That is also the essence of the proof, as well (summarized).

So the answer to your exact question is that it's not the key. It's using two different keys, each simply derived from the base key and you're forced to break them both.

I don't think this is correct. With HMAC, any collision in the inner function is immediately and automatically a collision for the full HMAC (same as for the construction that CodesInChaos asked about). So what you describe is not actually a benefit of HMAC.
–
D.W.Aug 1 '12 at 5:37