Key Derivation Functions

Work in progress. This note is still being written and incomplete.

A key derivation function (KDF) derives 1 or more cryptographic keys from a secret input value.

K=KDF(S,salt,info,L)K = \text{KDF}(S, \text{salt}, \text{info}, L)

Here:

  • SS: input secret, such as a password or a Diffie-Hellman shared secret
  • salt\text{salt}: non-secret random value
  • info\text{info}: context label binding the key to its purpose
  • LL: required output length

Raw secrets are unfit as keys directly.

  • A DH shared secret is a group element, not a uniformly random bit string.
  • A password has low entropy.
  • 1 secret must yield several independent keys, such as an encryption key and a MAC key.

Key Derivation Function Properties

A secure KDF satisfies:

  • Determinism
    The same inputs always give the same key.
  • Pseudo-randomness
    The output is computationally indistinguishable from a uniformly random string, as for a pseudorandom function.
  • One-wayness
    The input secret cannot be recovered from a derived key.
  • Independence
    Keys derived with different info\text{info} values are unrelated. Leaking 1 key reveals nothing about the others.

Key Derivation from High-Entropy Secrets

The input already has enough entropy, but is not uniformly distributed. This is the case for a DH shared secret.

HKDF is the standard construction, built on HMAC with a hash function HH.

  • Extract
    Compresses the input into a uniformly random pseudorandom key. PRK=HMACH(salt,S)\text{PRK} = \text{HMAC}_H(\text{salt}, S)
  • Expand
    Stretches PRK\text{PRK} into LL bytes of output keying material T=T1∥T2∥⋯T = T_1 \| T_2 \| \cdots. Ti=HMACH(PRK,Ti−1∥info∥i),T0=emptyT_i = \text{HMAC}_H(\text{PRK}, T_{i-1} \| \text{info} \| i), \quad T_0 = \text{empty}

The salt is optional here. A fixed or empty salt is acceptable.

Key Derivation from Passwords

The input has low entropy, so an attacker can guess candidates offline. The KDF must make each guess expensive.

  • Salt
    A unique random salt per password defeats precomputed tables and prevents identical passwords from giving identical keys.
  • Iteration count
    The hash is applied many times. Each guess costs the attacker the same work as the defender’s 1 derivation, multiplied by the count.
K=PBKDF2(HMAC,password,salt,c,L)K = \text{PBKDF2}(\text{HMAC}, \text{password}, \text{salt}, c, L)
  • cc: iteration count

PBKDF2 needs little memory, so GPUs and ASICs run many guesses in parallel. Memory-hard functions such as scrypt and Argon2 require a large amount of memory per guess, which limits this parallelism.

Key Hierarchy

1 master secret yields separate keys for each purpose by varying info\text{info}.

Kenc=KDF(S,salt,"encryption",L)Kmac=KDF(S,salt,"integrity",L)\begin{aligned} K_{\text{enc}} &= \text{KDF}(S, \text{salt}, \text{"encryption"}, L) \\ K_{\text{mac}} &= \text{KDF}(S, \text{salt}, \text{"integrity"}, L) \end{aligned}

Using the same key for encryption and integrity can break the security of both.

Examples:

  • TLS derives its session keys from the DH shared secret using HKDF.
  • Disk encryption derives its key from a user password using PBKDF2 or Argon2.
  • Password storage keeps KDF(password,salt)\text{KDF}(\text{password}, \text{salt}) instead of the password.
Written by September 29, 2026 3 min read
Was this helpful?