Files
skills/docs/security-stack/crypto/crypto-hash/src/kdf/hkdf/hkdf.md
2026-05-29 08:20:56 +01:00

3.5 KiB
Raw Blame History

hkdf

(no submodules)

Purpose

Provides HKDF (HMAC-based Key Derivation Function, RFC 5869) over SHA-256, SHA-384, and SHA-512. HKDF is the standard mechanism for stretching or diversifying key material — for instance, turning a Diffie-Hellman shared secret into one or more symmetric encryption keys. This module wraps the audited @noble/hashes HKDF implementation and constrains the algorithm surface to the HashAlgorithm union shared across @suaveplan/crypto-hash.

Features

  • hkdf(algo, ikm, options) — HKDF-Extract-and-Expand in one call
  • Supports SHA-256, SHA-384, SHA-512 via HashAlgorithm
  • Configurable output length (in bytes)
  • Accepts arbitrary salt and info context bytes
  • Deterministic: same inputs always produce the same key material

Usage: Basic Example

import { hkdf } from "@suaveplan/crypto-hash/kdf";

const ikm  = new Uint8Array(32).fill(0x01); // input key material
const salt = new Uint8Array(16);             // random salt (often public)
const info = new TextEncoder().encode("suaveplan-session-key-v1");

const sessionKey = hkdf("SHA-256", ikm, { salt, info, length: 32 });
console.log(sessionKey.length); // 32

Usage: Advanced Example

import { hkdf } from "@suaveplan/crypto-hash/kdf";
import { toHex } from "@suaveplan/crypto-hash/encoding";

// Derive separate encryption and MAC keys from a single DH shared secret
function deriveKeyPair(sharedSecret: Uint8Array, context: string): {
    encKey: Uint8Array;
    macKey: Uint8Array;
} {
    const encoder = new TextEncoder();
    const salt    = new Uint8Array(32); // zero salt; real usage uses random

    const encKey = hkdf("SHA-256", sharedSecret, {
        salt,
        info: encoder.encode(`${context}:enc`),
        length: 32,
    });
    const macKey = hkdf("SHA-256", sharedSecret, {
        salt,
        info: encoder.encode(`${context}:mac`),
        length: 32,
    });

    return { encKey, macKey };
}

const { encKey, macKey } = deriveKeyPair(new Uint8Array(32), "chat-session");
console.log(toHex(encKey));
console.log(toHex(macKey));

API Reference

hkdf(algo: HashAlgorithm, ikm: Uint8Array, options: HkdfOptions): Uint8Array

Derives options.length bytes of key material from the input keying material ikm using the two-step HKDF-Extract-and-Expand procedure.

Parameter Type Description
algo HashAlgorithm Underlying hash: "SHA-256", "SHA-384", or "SHA-512"
ikm Uint8Array Input keying material (e.g., DH shared secret)
options.salt Uint8Array Optional salt bytes (use a random or domain-specific value)
options.info Uint8Array Context and application-specific information
options.length number Number of output bytes to derive

Returns: Uint8Array of options.length bytes.


HkdfOptions

interface HkdfOptions {
    readonly salt: Uint8Array;
    readonly info: Uint8Array;
    readonly length: number;
}

Implementation Notes

HKDF is defined in RFC 5869. The Extract step computes PRK = HMAC(salt, ikm); the Expand step iterates HMAC(PRK, info || counter) until length bytes are produced. Both steps are performed by @noble/hashes/hkdf — no hand-rolled HMAC is involved here. The internal hasherFor helper is a private module function mapping HashAlgorithm strings to hash constructors; it is not exported. The maximum derivable length is 255 × hashLen, which for SHA-256 is 8160 bytes — well within any practical keying requirement.