← [ BACK_TO_NOTES ]

密钥派生函数(KDF)

KDF 从已有 secret/keying material 派生一个或多个用途隔离密钥;HKDF 面向高熵 key material 做 extract/expand,而 PBKDF2/Argon2 属于 password-based KDF,专门用 salt 与高计算/内存成本抵抗低熵口令猜测。

#concept #evergreen #crypto

[!info] related notes

密钥派生函数(KDF)

一句话定义

KDF 的目标是:

从已有 secret / keying material 派生出一个或多个适合具体用途的 cryptographic key。

但 KDF 并不只有一种。

至少要区分:

  • general-purpose key derivation;
  • password-based key derivation。

把所有 KDF 都理解成“故意很慢的哈希”是错误的。

General-Purpose KDF

这类 KDF 处理的输入通常已经具有足够 entropy,例如:

  • ECDHE shared secret;
  • master secret;
  • device secret;
  • root key。

典型目标:

  • extract entropy;
  • expand 成多个 subkeys;
  • domain separation;
  • key hierarchy;
  • protocol context binding。

代表:

  • HKDF。

它通常追求:

快速、确定、可证明地派生用途隔离 key。

而不是故意拖慢攻击者。

HKDF

HKDF 常分两步:

Extract
→ 把输入 keying material 压缩/规范成 pseudorandom key

Expand
→ 按 context/info 派生一个或多个 output key

典型用途:

  • TLS 1.3 key schedule;
  • protocol subkeys;
  • session key derivation。

因此:

HKDF 不是 password hashing function。

Password-Based KDF

Password entropy 通常很低。

人类密码例如:

  • dictionary word;
  • short phrase;
  • reused password;

不能直接作为 AES key。

Password-based KDF 要额外加入:

  • salt;
  • configurable work factor;
  • 某些算法的 memory cost;
  • parallelism control。

代表:

bcrypt 也属于 password hashing scheme,但其成本模型和输入边界与以上算法不同。

这里“慢”是设计目标之一。

Salt 的角色

随机 salt 主要解决:

  • 相同 password 产生不同 derived result;
  • 破坏通用 rainbow table;
  • 迫使 attacker 对每个 salt 重新计算。

Salt 通常不需要保密。

它与 secret pepper 不同。

Work Factor

Password KDF 的目标是让:

one password guess

具有可控成本。

对合法用户:

  • 几十到几百毫秒可能可接受。

对 attacker:

  • billions of guesses 会显著变贵。

参数需要随着硬件能力变化定期重新评估。

Memory-Hard KDF

Argon2id / scrypt 等还让攻击者为每次猜测付出显著 memory cost。

这削弱 GPU/ASIC 大规模并行爆破的成本优势。

KDF 与 Hash

Hash:

message → fixed-length digest

KDF:

secret/keying material + salt/context
→ key material

KDF 可能内部使用 hash / HMAC,但目标和安全模型不同。

KDF 与 Encryption

KDF 不负责把 plaintext 变成 ciphertext。

常见链路:

password
→ Argon2id
→ encryption key
→ AEAD
→ ciphertext

或:

ECDHE shared secret
→ HKDF
→ traffic keys
→ AEAD
→ TLS records

Domain Separation

从一个 root secret 派生多个用途 key 时,应该用不同 context/info:

root secret
→ KDF(“encryption”) → encryption key
→ KDF(“authentication”) → auth key

而不是把同一个 key 同时拿去做多个独立用途。

Bitwarden 场景

Password vault 常使用 password KDF:

master password
→ PBKDF2 / Argon2id
→ master key material

然后再保护 vault encryption key。

这里与 TLS 的 HKDF 完全不是同一 threat model。

常见误区

KDF 都必须故意很慢

错误。HKDF 这类 general-purpose KDF 不以慢为目标。

Password hash 只要 SHA-256 多算几次就够

不稳定。应使用标准 password KDF。

derived key 越多越危险

只要使用标准 KDF、正确 context/domain separation,从 root secret 派生多个独立用途 key 正是常见设计。

Salt 是 secret

通常不是。Salt 主要要求 unique/random,而非保密。

学习检查

  1. general-purpose KDF 与 password-based KDF 的 threat model 有什么不同?
  2. HKDF 为什么不应该故意很慢?
  3. PBKDF2/Argon2 为什么需要 work factor?
  4. Salt 解决什么问题,为什么通常不需要保密?
  5. KDF 与普通 Hash 的目标有什么差异?
  6. domain separation 为什么能减少 key reuse 风险?
  7. TLS 1.3 与 password vault 为什么虽然都用 KDF,但算法目标完全不同?
创建于 2026/7/11 更新于 2026/9/30
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本