Skip to content
HKDF — Key Derivation
step 1/5

Reading — step 1 of 5

Read

~1 min readCryptographic Primitives

HKDF — Key Derivation

TLS 1.3 derives MANY keys from a single shared secret: client-write-key, server-write-key, application-traffic-key, exporter-key, ...

HKDF (HMAC-based KDF, RFC 5869) is the standard:

HKDF-Extract(salt, IKM) = HMAC(salt, IKM)            -> PRK (32 bytes for SHA-256)
HKDF-Expand(PRK, info, L) = ...                      -> L bytes of OKM
  • Extract turns input keying material into a uniform PRK (pseudorandom key).
  • Expand stretches PRK into any number of context-tagged keys.
python

TLS 1.3 wraps this in HKDF-Expand-Label:

HKDF-Expand-Label(secret, label, context, length) =
    HKDF-Expand(secret, "tls13 " || label || context, length)

Each derived key includes a label (e.g. "c hs traffic" for client handshake traffic key) so different keys can never collide even if the same secret is reused.

The TLS 1.3 key schedule is a tree:

0  -> Early Secret -> binder_key, c_e_traffic, e_exp_master
       |
       v
       (with DH shared) -> Handshake Secret -> c_hs_traffic, s_hs_traffic
                          |
                          v
                          Master Secret -> c_ap_traffic, s_ap_traffic, exp_master, res_master

Each transition is HKDF-Extract; each branch is HKDF-Expand-Label.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…