ChaCha20-Poly1305 是什么
ChaCha20-Poly1305 是 RFC 8439 定义的认证加密组合:ChaCha20 流密码负责加密,Poly1305 消息认证码负责完整性,一次调用同时产出密文与 128 位标签。它是 TLS 1.3 的三个标准套件之一,也是 WireGuard 的数据面算法,在缺少 AES 硬件加速的设备上性能优势明显。
基本信息
| 标准 | RFC 8439 |
|---|---|
| 组成 | ChaCha20 加密 + Poly1305 认证 |
| nonce / 标签 | 96 位 / 128 位 |
| 密钥长度 | 256 位 |
| TLS 1.3 套件 | TLS_CHACHA20_POLY1305_SHA256 |
| 优势 | 无需硬件加速也快,便于常量时间实现 |
| 其他用途 | WireGuard、部分 VPN 与即时通信协议的数据面 |
典型使用场景
- TLS 1.3 与 1.2 套件:客户端无 AES 加速时优先协商,减少移动端 CPU 开销
- 移动端与物联网:ARM 设备上软件实现效率优于 AES,且不易受缓存侧信道影响
- VPN 与隧道:WireGuard 全量使用该算法保护数据包
- 即时通信与音视频:低延迟场景下的对称加密与完整性保护
- 对侧信道敏感的软件实现:常量时间特性让它在共享环境更安全
Python 使用示例
Python 使用示例
from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
import os
key = ChaCha20Poly1305.generate_key() # 256 位密钥
nonce = os.urandom(12) # 96 位 nonce,随密文一起存储
chacha = ChaCha20Poly1305(key)
ct = chacha.encrypt(nonce, b'payload', b'aad') # 第三参数为关联数据
pt = chacha.decrypt(nonce, ct, b'aad') # 认证失败抛 InvalidTag
assert pt == b'payload'与 AES-GCM 对照
| 维度 | ChaCha20-Poly1305 | AES-GCM |
|---|---|---|
| 标准 | RFC 8439 | NIST SP 800-38D |
| nonce / 标签 | 96 位 / 128 位 | 96 位 / 128 位 |
| 硬件依赖 | 无,软件实现即高效 | 有 AES-NI 时显著更快 |
| 侧信道特性 | 设计上易于常量时间实现 | 查表实现存在缓存时序风险 |
| TLS 1.3 套件 | TLS_CHACHA20_POLY1305_SHA256 | TLS_AES_128/256_GCM_SHA256/384 |
| 选用建议 | 移动端与无加速平台优先 | 服务器端有 AES-NI 时优先 |
Poly1305 的密钥由 ChaCha20 密钥与 nonce 派生,因此 nonce 在同一密钥下必须唯一。重复使用 nonce 会直接泄漏认证密钥,攻击者可伪造消息;这条约束与 AES-GCM 对 nonce 的要求同样严格。
TLS 1.3 部署时常把 ChaCha20-Poly1305 排在 AES-GCM 之后,仅当客户端没有 AES 加速或服务端策略偏好时才优先选用。这样服务器端有 AES-NI 时走 AES-GCM,移动端自动落到 ChaCha20,兼顾两端性能。