深色模式
按功能组织:哈希函数 → MAC/KDF → Merkle 结构 → 密码存储。
哈希函数
参考:FIPS 180-4 SHA · FIPS 202 SHA-3
安全性质
- 抗原像:给定 h,难找 m 使 H(m)=h
- 抗第二原像:给定 m,难找 m'≠m 使 H(m')=H(m)
- 抗碰撞:难找任意 m≠m' 使 H(m)=H(m')
算法选型
| 算法 | 输出 | 构造 | 状态 |
|---|---|---|---|
| MD5 | 128 bit | Merkle-Damgård | 已破碰撞,禁止安全用途 |
| SHA-1 | 160 bit | Merkle-Damgård | 已破碰撞,弃用 |
| SHA-256/512 | 256/512 bit | Merkle-Damgård | 通用首选 |
| SHA-3 | 可变 | Sponge (Keccak) | 与 SHA-2 不同构造 |
<ul>
<li><strong>生日攻击</strong>:n bit 输出约 2^{n/2} 次可找碰撞;输出长度不能省</li>
</ul>
MAC 与 KDF
参考:RFC 2104 HMAC · RFC 5869 HKDF · RFC 9106 Argon2
MAC
- HMAC:H(K' ⊕ opad || H(K' ⊕ ipad || m));密钥化完整性校验
- 勿用裸哈希 H(m||k)(长度扩展攻击)
KDF 选型
| KDF | 输入 | 场景 |
|---|---|---|
| HKDF | 共享秘密 + salt + info | TLS 密钥派生、协议密钥拉伸 |
| PBKDF2 | 密码 + salt + 迭代 | 旧标准密码存储 |
| scrypt | 密码 + salt + 内存参数 | 内存硬,抗 ASIC |
| Argon2id | 密码 + salt + 参数 | 新系统首选(2015 PHC 冠军) |
Merkle 结构
- Merkle 树:叶子为数据哈希,内部节点为子节点拼接后哈希
- Merkle 证明:O(log n) 证明某叶子在树中——轻节点验证
- 证书透明度(CT):CA 签发日志,Merkle 树公开审计
- 区块链:交易 Merkle 根写入区块头
练习:实现 Merkle 证明的生成与验证。
密码存储
- 存储的是密码的加盐哈希,不是加密(不可逆)
- 每个用户独立随机盐;Argon2id 参数随硬件演进调整
- 比较哈希用常量时间函数,防 timing 泄露
- 域分离:不同用途的密钥用 HKDF info 区分
工程实践
| 语言 | 库 | 用途 |
|---|---|---|
| Python | hashlib、hmac.compare_digest | SHA-256、常量时间比较 |
| Python | argon2-cffi | 密码存储 |
| Rust | sha2、hmac、hkdf、argon2 | 哈希、MAC、KDF |
| Rust | subtle | 常量时间比较 |
<p class="kb-note-inline">练习:Argon2id 用户注册流程。</p>