HKDF is a key derivation function (KDF) based on the HMAC function.

Algorithm

The HKDF algorithm consists of two stages, extract and expand. These steps are referred to as HKDF-Extract and HKDF-Expand in RFC5869.

HKDF-Extract

// TODO: Write this section

HKDF-Expand

// TODO: Write this section

Python implementation

For this example, we will use the HMAC-MD5 function. Let’s get the output length as we’re going to need it soon.

In [2]:
output = hmac_md5(b"test", b"test")

hash_length = len(output)

hash_length
Out [2]:
16

HKDF-Extract

In [3]:
def hkdf_extract(input_key, salt = b""):
    if not salt:
        salt = bytes([0] * hash_length)
    return hmac_md5(salt, input_key)
In [4]:
hkdf_extract(b"Test key").hex()
hkdf_extract(b"Test key", b"Test salt").hex()
Out [4]:
'960b6c2f21572a3c87362f1b27c3ccf4'
Out [4]:
'042745b0ee9780ad3b9e9d39503f35c8'

HKDF-Expand

In [5]:
def hkdf_expand(key, info = b"", length = 32):
    result = b""
    
    t = b""
    i = 1
    while len(result) < length:
        t = hmac_md5(key, t + info + bytes([i]))
        result += t
        i += 1
    return result[:length]
In [6]:
key = hkdf_extract(b"Test key")

hkdf_expand(key).hex()
Out [6]:
'c465ec2a532988a9e3ec5f99aa848876b0aaf7252cbabb5c73e907137ebb3838'

HKDF

In [7]:
def hkdf(input_key, salt = b"", info = b"", length = 32):
    prk = hkdf_extract(input_key, salt)
    return hkdf_expand(prk, info, length)
In [8]:
hkdf(b"Test key", info=b"Game map").hex()
hkdf(b"Test key", info=b"Game config").hex()
Out [8]:
'd422024f7acbc35680634d0346b96cae258cc966dd7458e628e2fb23f38ef2b8'
Out [8]:
'eb74c5414916a88f635c9188e668ff5cf31b52e35539e545f03366972ff2f6b4'

Useful links and references