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…