Summary
- HKDF salt is normally non-secret. It can strengthen extraction by separating uses and supporting independence, but it cannot manufacture entropy, authenticate the input or make password guessing expensive.
- The
infoinput has a different job: it binds expanded keys to a protocol, version, role, transcript or purpose. A successful derivation is trustworthy only when the provenance of the input, salt, encoded context and output role is preserved.
Two identical secrets enter different rooms
Imagine a service that receives one shared secret and needs three outputs: an encryption key, an initialization vector and a header-protection key. The team feeds the same bytes to the same KDF three times. The calls succeed, the lengths look right and both endpoints agree. Yet if the calls carry no distinct context, the service has not established which output belongs to which job. It has produced bytes, not a defensible key schedule.
This is the practical problem hidden by the casual phrase “hash the secret.” Key derivation is not merely a way to make a string look random. It must transform source material under explicit assumptions, then keep outputs apart across algorithms, protocol versions, directions and lifetimes.
Hugo Krawczyk gave that division a durable form in the HKDF design and its analysis. RFC 5869, coauthored with Pasi Eronen, calls the pattern extract-then-expand. Krawczyk’s underlying paper supplies the formal rationale: first obtain a pseudorandom key from input material that may not itself be uniform; then use that key to produce the particular outputs an application needs. The IETF record also credits Krawczyk as a coauthor of HMAC, the primitive used by HKDF. ACM’s 2025 awards record recognized his broader work on the foundations and deployed protocols of secure communications.
The biography matters here only because one design decision has travelled so far: the middle of a key schedule deserves its own boundary.
Extract does not mean create
HKDF-Extract takes two inputs, salt and initial keying material, or IKM, and returns a pseudorandom key, PRK:
PRK = HMAC-Hash(salt, IKM)
The operation is an extractor, not an entropy generator. If the IKM contains dispersed uncertainty, extraction can concentrate it into a fixed-length value suitable as an HMAC key. It cannot add uncertainty that was absent. An attacker who can cheaply enumerate every plausible IKM can run the same extraction for every guess.
That distinction becomes concrete with Diffie–Hellman. The shared group element is not generally modelled as an already uniform pseudorandom HMAC key, so RFC 5869 says the extract step should not be skipped for a Diffie–Hellman value. By contrast, an input that is already a strong pseudorandom key can sometimes go directly to Expand. “Sometimes skippable” is therefore a statement about the source distribution and representation of IKM, not an optimization switch to flip because a benchmark is slow.
NIST SP 800-56C Rev. 2 uses the same architectural vocabulary—extraction, expansion and extraction-then-expansion—for key establishment. That wider standardization is useful evidence. The boundary is not cosmetic naming from a single implementation; it is a way to state what has and has not been established before a key acquires a purpose.
Why a public salt still matters
In RFC 5869, salt is optional and normally non-secret. When it is omitted, HKDF substitutes a hash-length string of zero octets. A protocol can transmit a salt in the clear, derive it from authenticated public nonces or reuse a suitable fixed value without pretending it is another key.
Public does not mean useless. A well-chosen salt strengthens the analytical basis of extraction, can make different uses of the hash function independent and supports source-independent extraction. Even a salt with limited entropy can help. Its benefit does not come from an attacker being unable to read it.
Nor does non-secret mean “let anyone choose it.” RFC 5869’s independence guidance says salt should be independent of IKM. When a protocol relies on nonces to form it, those nonces must be authenticated against adversarial selection. An operations record should therefore distinguish four states that dashboards often collapse: absent salt, fixed protocol salt, fresh authenticated public salt and attacker-influenced salt. All four values may be visible. They do not carry the same assurance.
RFC 8188 offers a clean deployed example. Its encrypted HTTP content coding maps a transmitted salt into HKDF-Extract, while a fixed string naming the content encoding goes into info for expansion. The two values coexist because visibility is not their distinguishing feature. One participates in extracting a PRK from the keying material; the other names the use of an output.
Salt is not password hardening
The word “salt” causes a dangerous category jump because it also appears in password storage. In that setting, a unique salt frustrates precomputed tables and separates identical passwords, but the password remains low-entropy material. Defenders also need deliberate computational cost.
HKDF has no built-in work factor and no memory-hard phase. RFC 5869 says this directly: extraction can concentrate existing entropy but cannot amplify it, and HKDF does not include the slowdown expected from a password KDF. Applying HKDF one time to a human password may produce output with the visual shape of a key, but it leaves an offline attacker with a cheap guessing function.
PBKDF2 makes an iteration count an explicit parameter. Argon2 goes further by making memory cost, passes and parallelism part of the design, with Argon2id recommended for password hashing. These mechanisms do not make a weak password magically strong, but they alter the economics of testing guesses. A public salt in HKDF serves a different security argument. Sharing a noun does not make the controls interchangeable.
This boundary matters in reviews and incident response. “We salted it” is not an adequate answer. The reviewer must ask which construction consumed the salt, what the source material was, whether guesses are cheap, what cost parameters were enforced and whether the salt’s required independence or uniqueness was actually maintained.
info is where a key learns its job
After extraction, HKDF-Expand takes PRK, an info value and a requested length. RFC 5869 describes info as application- and context-specific information. It can name a protocol, algorithm, identity or length, and it is intended to stop the same IKM from yielding indistinguishable material for different contexts.
That job cannot be moved casually into salt. Salt shapes extraction; info separates uses during expansion. RFC 5869 even discourages returning PRK directly as the final output when it would bypass info, and advises against adding the contextual material to Extract as a substitute. A PRK is a useful intermediate secret, not a key whose role has already been established.
TLS 1.3 makes the separation visible in its wire-level design. HKDF-Expand-Label prefixes labels with tls13 and can bind a transcript hash as context. The schedule derives values with names such as finished, key and iv. Those labels are not documentation comments. They are encoded input to the cryptographic computation.
QUIC reuses the TLS 1.3 expansion construction but adds its own purposes. RFC 9001 derives an AEAD key, IV and header-protection key under the distinct labels quic key, quic iv and quic hp; it explicitly says the labels provide separation between QUIC and TLS. If a logging system records only “HKDF-SHA256 succeeded,” it discards the evidence that explains which key was meant to exist.
HPKE is more explicit still. Its LabeledExtract and LabeledExpand inputs include the string HPKE-v1, a ciphersuite identifier and a purpose label. This binds secrets to the scheme, version and selected algorithms. MLS uses its own MLS 1.0 prefix and labeled schedule to derive separate epoch secrets. These are independent protocol designs, not syntactic variations of one master template. Their common lesson is that a label is part of the security domain only when every participant encodes and validates it consistently.
Four receipts for a derivation
A defensible key schedule leaves more than an output fingerprint.
The first receipt is source provenance. Record whether IKM came from an authenticated Diffie–Hellman exchange, a random key, a pre-shared secret, a password or another derivation. These inputs can have the same byte length and radically different entropy and attacker-control assumptions.
The second is salt provenance. Preserve its exact bytes, generation rule, authentication status, reuse policy and relationship to IKM. “Public” is a confidentiality statement; it is not a provenance statement.
The third is encoded context. Store the exact label, protocol/version prefix, ciphersuite, role, transcript hash and length encoding that reached Expand—not merely a friendly label printed by the application. Ambiguous concatenation or inconsistent canonicalization can erase separation while logs continue to look sensible.
The fourth is output custody. Name whether an output is a key, IV, exporter, resumption secret or intermediate PRK; record its owner, permitted operations, epoch and deletion point. A correct key used under the wrong nonce policy or retained beyond its generation is still an operational failure.
Together, these receipts keep a deterministic primitive from being mistaken for an oracle. Matching outputs show that two implementations supplied equivalent inputs to equivalent algorithms. They do not prove that the input was unpredictable, the peers were authenticated, the context was the intended one or the old key was destroyed.
Sources
- RFC 5869 — HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
- Cryptographic Extraction and Key Derivation: The HKDF Scheme
- Hugo Krawczyk’s IETF Datatracker profile
- ACM Awards Booklet 2025
- NIST SP 800-56C Rev. 2
- RFC 8446 — The Transport Layer Security (TLS) Protocol Version 1.3
- RFC 9001 — Using TLS to Secure QUIC
- RFC 9180 — Hybrid Public Key Encryption
- RFC 9420 — The Messaging Layer Security (MLS) Protocol
- RFC 9106 — Argon2 Memory-Hard Function
- RFC 2898 — PKCS #5: Password-Based Cryptography Specification Version 2.0
- RFC 8188 — Encrypted Content-Encoding for HTTP
Member Briefing
Deeper Profile Context
Sign in with the right membership level to unlock the full briefing and source notes.
Only for Strategic Circle
Strategic Circle
Open to all readers. Unlock profile briefings after joining and signing in.
Join Strategic CircleOnly for Leadership Alliance
Leadership Alliance
For qualified IP-asset owners and management; sign in to unlock alliance briefings.
Join Leadership Alliance
