了解流加密模式伪随机算法
1 简介
一次一密(OTP)的安全本质
OTP 的信息论安全性来自三点:
密钥是真随机的
密钥长度 ≥ 明文长度
每个密钥只使用一次
加密方式:
C=P⊕K
只要满足以上条件,密文不泄露任何关于明文的信息(Shannon 证明)。

- OTP 的致命缺点 :
密钥太长
难以分发和管理
现实中几乎不可用
2 ChaCha20 / Salsa20 的核心思想
现代伪随机流加密算法(如ChaCha20、Salsa20)它们做了一件非常“工程化但聪明”的事情:
用一个短密钥 + PRNG,扩展出“看起来像真随机”的长密钥流
形式上:
Keystream = PRNG(key, nonce, counter)
Ciphertext = Plaintext ⊕ Keystream
关键假设是:
在可行计算资源内,攻击者无法区分该密钥流和真正随机序列
这在密码学中称为:
计算不可区分性(computational indistinguishability)
- 为什么这在理论上“逼近 OTP”
对比两者:
属性 OTP ChaCha20 / Salsa20
密钥来源 真随机 伪随机(PRNG)
密钥长度 = 明文长度 固定(256 位)
安全性 信息论安全 计算安全
XOR 结构 是 是
如果满足以下条件:
PRNG 是密码学安全的(CSPRNG)
攻击者无法在现实时间内区分密钥流和真随机
nonce / counter 从不复用
那么从攻击者视角看:
密文的统计行为 ≈ OTP 密文
ChaCha20 是“在计算意义下的 OTP 仿真器”
3 PRNG 在这里为什么足够强
ChaCha / Salsa 的 PRNG 不是普通线性同余生成器,而是:
基于 ARX 结构(Add-Rotate-XOR)
高扩散(avalanche effect 极强)
经过多年公开分析(eSTREAM、TLS、SSH、QUIC)
目前为止:
无实用的区分攻击
无已知密钥恢复攻击
- 但它们仍然不等于 OTP
关键差异:
不是信息论安全
假设 PRNG 可被破解 → 历史密文全部暴露
nonce 不能复用
同一 (key, nonce) → 两个密文 XOR = 明文 XOR
这点和 OTP 重用密钥是同一个灾难
必须防篡改
原始流加密是 malleable 的
所以现实系统中通常使用:
ChaCha20-Poly1305(AEAD)
4 Go 语言中支持 ChaCha20 / Salsa20 的库
官方维护(强烈推荐)
golang.org/x/crypto/chacha20
纯流加密接口
import "golang.org/x/crypto/chacha20"
特点:
RFC 8439 ChaCha20
提供原始 keystream XOR
适合研究 / 底层协议
不提供认证(MAC)
golang.org/x/crypto/chacha20poly1305
现实中最该用的
import "golang.org/x/crypto/chacha20poly1305"
特点:
AEAD(加密 + 认证)
TLS 1.3 / QUIC / OpenSSH 都在用
nonce 管理清晰
抗重放 / 抗篡改
生产环境首选
golang.org/x/crypto/salsa20
import "golang.org/x/crypto/salsa20"
特点:
支持 Salsa20 / XSalsa20
历史算法,仍安全
新项目一般更偏向 ChaCha20
- Go 标准库中的接口
虽然 crypto/ 里没有直接实现 ChaCha/Salsa,但有统一抽象:
type Stream interface {
XORKeyStream(dst, src []byte)
}
ChaCha20 / Salsa20 都实现了该接口,方便组合。
-
第三方 / 扩展生态
libsodium(通过 cgo) XSalsa20 / XChaCha20 Cloudflare / WireGuard 相关实现 Go QUIC / TLS 实现
5 小结
ChaCha20 / Salsa20 用“不可区分于随机的密钥流”在计算意义上复刻了一次一密,
在正确使用 nonce、并配合认证(AEAD)的前提下,是现代密码工程中最接近 OTP 的现实方案。
- 点赞
- 收藏
- 关注作者
评论(0)