HMAC is a cryptographic MAC (message authentication code) that uses a cryptographic hash function and a secret key.
Use cases
HMAC was designed as a message authentication code, but over time it has found use for other purposes. HMAC is commonly used as a keyed hash function. The use cases include:
- One-time passwords using TOTP / HOTP.
- Key-derivation with HKDF.
Algorithm
Key processing
The hash function is assumed to process its input in N-byte blocks. The first step of the HMAC algorithm turns an arbitrary-length key into a block-sized key.
First; if the key is longer than the block size, it is hashed with the hash function. Afterwards; the key is padded with 0x00
bytes on the right until it is block-sized.
The result is a key that has the same length as a hash block.
Inner and outer padding
Two padding blocks are generated, both of them block-sized. An inner pad (called ipad) and an outer pad (called opad).
Hashing
Python implementation
def make_hmac(fn, block_size): def inner(key, buf): if len(key) > block_size: key = fn(key) while len(key) < block_size: key += b"\x00" outer_pad = bytes([x ^ 0x5c for x in key]) inner_pad = bytes([x ^ 0x36 for x in key]) return fn(outer_pad + fn(inner_pad + buf)) return inner
HMAC-MD5
def md5(buf): return hashlib.md5(buf).digest() hmac_md5 = make_hmac(md5, 64)
hmac_md5(b"key", b"The quick brown fox jumps over the lazy dog").hex()
'80070713463e7749b90c2dc24911e275'
HMAC-SHA1
def sha1(buf): return hashlib.sha1(buf).digest() hmac_sha1 = make_hmac(sha1, 64)
hmac_sha1(b"key", b"The quick brown fox jumps over the lazy dog").hex()
'de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9'
Test vectors
The following values can be used to confirm if an HMAC implementation is behaving correctly.
HMAC-MD5
- Key: key
- Message: The quick brown fox jumps over the lazy dog
-
Output: 80070713463e7749b90c2dc24911e275
- Key: key
- Message: Hello, world!
- Output: 8013adbd3f9eff856800e8d3a7077cef
Useful links and references
- HMAC on Wikipedia
- RFC2104 - HMAC: Keyed-Hashing for Message Authentication
- FIPS 198-1 - The Keyed-Hash Message Authentication Code (HMAC)