leo.blog();

Hmac

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:

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

In [2]:
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

In [3]:
def md5(buf):
    return hashlib.md5(buf).digest()

hmac_md5 = make_hmac(md5, 64)
In [4]:
hmac_md5(b"key", b"The quick brown fox jumps over the lazy dog").hex()
Out [4]:
'80070713463e7749b90c2dc24911e275'

HMAC-SHA1

In [5]:
def sha1(buf):
    return hashlib.sha1(buf).digest()

hmac_sha1 = make_hmac(sha1, 64)
In [6]:
hmac_sha1(b"key", b"The quick brown fox jumps over the lazy dog").hex()
Out [6]:
'de7c9b85b8b78aa6bc8a7a36f70a90701c9db4d9'

Test vectors

The following values can be used to confirm if an HMAC implementation is behaving correctly.

HMAC-MD5

Useful links and references

Leave a Comment