“流密码把短种子扩展成长密钥流,追求的是有计算限制的攻击者无法区分,而不是长流真的获得了更多熵。一个确定性生成器的输出熵至多等于种子熵;它绕开的不是 Shannon 证明,而是把安全目标改成了…”
形式陈述
流密码由秘密密钥生成一段密钥流,再逐位或逐字节与明文组合。典型的同步异或流密码可写为
其中
支持分块生成的方案还会用计数器或位置
直觉
一次一密用与消息等长的真正随机秘密比特遮住明文;流密码则让双方只共享短密钥,通过同一个确定计算生成长流。它保留了异或操作的简单性,把存储和分发长密钥的成本换成计算安全假设。
一个限于单次消息的构造是取均匀短密钥
生成得更长不表示熵凭空增加:在密钥和公开参数固定后,整段流已经确定。伪随机性说的是受计算资源限制的对手难以区分它与随机流,不是短密钥生成了信息论意义上的独立随机比特。
nonce 的工作也不同于密钥。密钥负责不可知性,nonce 帮助同一密钥下的不同加密使用不同流;在要求 nonce 唯一的方案中,它可以是公开计数器,不必保密,也不必每次随机抽取。独立随机选择仍需要考虑碰撞,不能把“随机”直接当作“唯一”。
例子与边界
重复的不是名字,而是密钥流位置
用同一段
例如用流字节 6c 加密明文字节 41 和 42,得到密文字节 2d 与 2e;二者异或为 03,恰好等于 41 xor 42。这里的数值均为十六进制。攻击者尚不一定直接知道两条明文,却已经获知它们之间的确定关系;若知道一条明文,还能由
因此需要避免的是同一密钥下重用相同密钥流位置。对常见 nonce 加计数器构造,重复相同
异或加密没有自动提供完整性
若攻击者把密文改成
攻击者即使不知道原明文,也能指定哪些位翻转。这不是密钥流预测失败,而是裸异或结构的可塑性。仅对消息做加密,不会自动产生“未经修改”的证据。
认证加密把机密性和篡改检测组合起来;AEAD 还能认证不加密的关联数据,例如消息类型或序号。认证标签不是靠给密文附上一个普通公开哈希就获得的,其生成与验证必须遵守具体方案。
同步方式与数据边界
同步流密码要求双方用相同位置的流解密。若一个连续字节流丢失数据,却没有长度、序号或重新定位机制,后续流会错位。独立分组使用各自 nonce、或使用方案支持的计数器定位,则可以在正确分组边界重新开始,不必把错误永久传播到所有后续消息。
自同步流密码是另一类结构:内部状态依赖有限段已收到的密文,在模型规定的条件下可以恢复同步。这与前面的公开 nonce、计数器式同步流不是同一假设;“流密码”不意味着所有方案都能任意跳到某个字节解密。
推论与应用
ChaCha20 展示的一种具体接口
RFC 8439 中的 ChaCha20 使用
同一 RFC 还定义 ChaCha20–Poly1305,将流加密与认证组合为 AEAD。此时 nonce 重复不仅会重复流,还会重复相应的一次性认证密钥,因此不能把“已经加上认证”理解成取消了 nonce 规则。实际使用应调用完整方案接口,而不是临时拼接流密码与标签计算。
与分组密码的关系
分组密码本身是固定长度块上的密钥置换;流密码提供按需生成并与数据组合的密钥流。分组密码的 CTR 模式可以构造流式加密,所以区别不在于程序是否按块运行,而在于原语提供什么对象、工作模式怎样使用它。
流密码适合处理任意长度消息和逐段到达的数据,但具体延迟、随机访问与吞吐量还取决于构造。基本异或加密通常保持消息长度;隐藏内容并不自动隐藏长度、分组边界或到达时间。把伪随机生成、流位置管理和认证这三层分别说明,才构成完整的使用语义。
流密码属于对称加密:通信双方利用共享密钥生成一致的密钥流。
参考资料
- Yoav Nir and Adam Langley, RFC 8439: ChaCha20 and Poly1305 for IETF Protocols, 2018,§§2.3–2.4、2.8、4,参数、AEAD 构造及 nonce 要求。
- Dan Boneh and Victor Shoup, A Graduate Course in Applied Cryptography, version 0.6, 2023,Chapter 3 “Stream Ciphers” 及认证加密相关章节。
- Jonathan Katz and Yehuda Lindell, Introduction to Modern Cryptography, 3rd ed., CRC Press, 2020,伪随机性、计算安全加密与消息认证。