[ Log On ]
  • Home
  • Tst
  • Cha
  • Enc
  • Code
  • IP
  • Fun
  • Sub
  • DigF
  • Cis
  • Com
  • Db
  • About
  • Netsim

HKDF - HMAC Key Derivation function

[Back] HMAC Key Derivation function (HKDF) is used to derive an encryption key from a pass phrase. Initially HKDF creates a pseudorandom key (PRK) using a pass phrase and a salt value (and any other random functions which are relavent), in order to produce an HMAC hash function (such as HMAC-SHA256), andalong with a salt value. Next the PRK output is used to produce a key of the required length. If we generate a 16-byte output (32 hex characters), we have a 128-bit key, and a 32-byte output (64 hex characters) will generate a 256-bit key. HKDF is used in TLS 1.3 for generating encryption keys:

Passphrase and salt

Passphrase:

Salt (hex):

Key length (Bytes):

Hashing:


Sample run

A sample run is

Message:	hello123
Salt:		8e94ef805b93e683ff18
===================
PRK:	e229a4a30ea99b3bac27d233cef0d1feb4be4dcf6531f86d9ce521f9b5af19324fdeb74622bbb52353563cbd37a552c615daf696541f461428aaa39481c60559
Key:		e786fca9472ab083e5bb84c55fe6b581

In this case we have a hash of "e786fca9472ab083e5bb84c55fe6b581" which is 32 hex characters, and is thus 128-bits (16 bytes).

Code

An outline of the code is:

import sys
from binascii import unhexlify,hexlify,b2a_base64
import hashlib
import hmac

def hkdf_extract(salt, input_key_material, hash=hashlib.sha512):

	hash_len = hash().digest_size
	if salt == None or len(salt) == 0:
	  salt = chr(0) * hash_len
	return hmac.new(salt, input_key_material, hash).digest()

def hkdf_expand(pseudo_random_key, info="", length=32, hash=hashlib.sha512):

	hash_len = hash().digest_size
	length = int(length)
	blocks_needed = length / hash_len + (0 if length % hash_len == 0 else 1) 
	okm = ""
	output_block = ""
	for counter in range(blocks_needed):
	 output_block = hmac.new(pseudo_random_key, output_block + info + chr(counter + 1), hash).digest()
	 okm += output_block
	return okm[:length]

password='hello'
salt="8e94ef805b93e683ff18"

prk = hkdf_extract(unhexlify(salt), password)
key = hkdf_expand(prk, b"", 16)

print "Message:\t",password
print "Salt:\t\t",salt
print "==================="
print "Key (Hex):\t\t",hexlify(key)
print "Key (Base-64):\t\t",b2a_base64(key)

For the hashing function we could use md5(), sha1(), sha224(), sha256(), sha384(), or sha512().