Add kdf module: Key Derivation Function API (JEP 510, final in JDK 25), HKDF, RFC 5869 vectors, interop with Python cryptography and openssl, per-tenant keys

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017ic4b7rnC7jppGGdHGESvy
This commit is contained in:
2026-10-28 18:07:57 +00:00
co-authored by Claude Sonnet 5.5
parent c93a1fffbb
commit eca73ad544
21 changed files with 995 additions and 0 deletions
+27
View File
@@ -0,0 +1,27 @@
#!/usr/bin/env python3
"""Generate interop/cases.tsv: random HKDF inputs plus the expected OKM from Python's `cryptography` package
(a thin wrapper over OpenSSL's HKDF). Deterministic: fixed seed, so the file is byte-stable.
Columns: hash <TAB> ikm <TAB> salt <TAB> info <TAB> length <TAB> okm (hex; an empty field is an empty value)"""
import random, sys
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
HASHES = {"SHA256": hashes.SHA256, "SHA384": hashes.SHA384, "SHA512": hashes.SHA512}
SIZE = {"SHA256": 32, "SHA384": 48, "SHA512": 64}
rnd = random.Random(5869)
def rb(n): return bytes(rnd.getrandbits(8) for _ in range(n))
rows = []
for h in HASHES:
for i in range(100):
ikm = rb(rnd.choice([1, 16, 22, 32, 64, 100]))
salt = b"" if i % 5 == 0 else rb(rnd.choice([1, 13, 32, 80]))
info = b"" if i % 7 == 0 else rb(rnd.choice([1, 10, 40, 80]))
length = rnd.choice([1, 16, 32, 42, SIZE[h], SIZE[h] + 1, 82, 255 * SIZE[h]]) if i % 10 else 255 * SIZE[h]
okm = HKDF(algorithm=HASHES[h](), length=length, salt=salt or None, info=info).derive(ikm)
rows.append((h, ikm.hex(), salt.hex(), info.hex(), str(length), okm.hex()))
with open(sys.argv[1], "w") as f:
for r in rows: f.write("\t".join(r) + "\n")
print(f"wrote {len(rows)} cases")