消息认证码(MAC)
消息认证码(Message Authentication Code)是用于验证消息完整性和来源真实性的短固定长度值。
发送方用共享密钥 K 计算 MAC 值 t = MAC(K, M),将 (M, t) 一起发送。接收方用相同密钥重新计算 t' = MAC(K, M),验证 t' = t。
HMAC(Hash-based MAC)
基于哈希函数的 MAC,可与任何安全哈希函数搭配使用(如 HMAC-SHA256)。
HMAC(K, M) = H((K ⊕ opad) || H((K ⊕ ipad) || M))
其中 ipad = 0x36 重复,opad = 0x5C 重复。双层哈希结构防止长度扩展攻击。
HMAC 的安全性可以归约到底层哈希函数的抗碰撞性。
CMAC(Cipher-based MAC)
基于分组密码(如 AES)的 MAC。使用 CBC 模式处理消息,最后一组密文块作为 MAC 值。
认证加密(AEAD)
认证加密(Authenticated Encryption with Associated Data)同时提供:
- 机密性(加密)
- 完整性(检测篡改)
- 认证性(确认来源)
"Associated Data"(关联数据)是指需要认证但不需要加密的数据,如网络包头。
常见 AEAD 模式
- AES-GCM:CTR 模式加密 + GHASH 认证。TLS 1.3 默认模式。性能极高(有 AES-NI 硬件加速时)。
- ChaCha20-Poly1305:ChaCha20 流密码加密 + Poly1305 认证标签。在没有 AES 硬件加速的设备(如手机)上比 AES-GCM 快。
- AES-CCM:CBC-MAC 认证 + CTR 加密。用于 WiFi(WPA2)、蓝牙。
为什么需要 AEAD
先加密后 MAC(Encrypt-then-MAC)是安全的方式,但先 MAC 后加密(MAC-then-Encrypt)或只加密不认证都可能导致漏洞。AEAD 模式将两者一体化,避免实现错误。
密钥派生函数(KDF)
密钥派生函数将一个输入密钥材料(如密码、共享密钥)转换为符合密码学要求的密钥。
PBKDF2
Password-Based Key Derivation Function 2,NIST 标准。通过反复迭代 HMAC 来增加暴力破解的成本:
DK = T₁ || T₂ || ... || Tdklen/hlen
T₁ = PRF(Password, Salt || 0x01)
Ti = PRF(Password, Ti-1)
迭代次数可配置(建议 ≥ 600,000 次用于 HMAC-SHA256)。缺点:抗 GPU/ASIC 攻击能力弱(内存需求低)。
bcrypt
1999 年设计,基于 Blowfish 算法。特点:内置盐值、可调代价因子、使用大量内存(4 KB),比 PBKDF2 更抗 GPU 攻击。
scrypt
2009 年由 Colin Percival 设计(用于 Tarsnap 备份服务)。特点:需要大量内存(可配置),使得 ASIC/FPGA 实现代价极高。
Argon2
2015 年密码哈希竞赛(PHC)获胜者。有三个变体:
- Argon2d:抗 GPU 攻击最强,但可能受侧信道攻击
- Argon2i:抗侧信道攻击最强
- Argon2id:混合模式,目前最推荐的密码哈希方案
参数:时间代价 t、内存代价 m(KB)、并行度 p。建议至少 m=65536(64 MB)、t=3、p=4。