HMAC is a keyed-hash message authentication construction: a secret key and message produce a tag that supports message integrity and sender authentication. Unlike secret-prefix or secret-suffix MACs, HMAC hashes the input twice with separate inner and outer key transformations. section 7.0 section 7.5
Figure 7.12 HMAC(key, message) = Houter(key || Hinner(key || message))
HMAC follows the nested construction HMAC(K, m) = Houter(K || Hinner(K || m)), preventing a digest from exposing a resumable internal hash state. section 7.5
For a block-sized key K′, HMAC computes H((K′ XOR opad) || H((K′ XOR ipad) || m)). A key longer than the hash block size is hashed first; ipad and opad create distinct intermediate keys. section 7.5
The construction addresses two failures of simpler hash-based MACs:
- Secret-prefix MACs, H(key || message), expose a length-extension attack when built from Merkle–Damgård hashes. section 7.2 section 7.3.2
- Secret-suffix MACs, H(message || key), can succumb to collision attacks, including the RADIUS weakness involving MD5. section 7.2 section 7.5
- HMAC resists both attack classes because extending the outer authentication tag does not produce a valid inner digest, while forging collisions requires the secret key. section 7.5
Forging a vulnerable API request
A secret-prefix transaction API authenticated an original amount of 10. By resuming SHA-256 from the published digest and adding padding plus amount=424242, an attacker produced a new authenticated request without the API secret. Replacing the direct hash with HMAC prevents this length-extension path. section 7.3.2



