Caloogy 文章
English

一次一密与香农:唯一被证明"绝对安全"的密码

日期
2026 年 9 月 27 日
系列
密码学
阅读
4 分钟
主题
One time padPerfect secrecyShannonXOR

一句话版本

用一串真随机、和消息一样长、只用一次的密钥,把消息逐位异或(或逐字母相加),得到的密文对任何人(包括拥有无限算力的人)都毫无信息。 原因是:在群里加上一个均匀随机的元素,结果仍是均匀随机的。香农在 1949 年证明了这一点,也证明了代价:密钥至少要和消息一样长。

全文分三层:

  1. 通俗理解:为什么"什么都可能"等于"什么都不知道"
  2. 实际用处:华盛顿–莫斯科热线、Venona 计划,以及现代加密为什么不用它
  3. 数学原理:完美保密的定义与证明、密钥长度下界、两次一密的崩溃,附手算例子

第一层:通俗理解

1.1 加法加密

把字母换成数字(A=0, B=1, …, Z=25),明文每个字母加上对应位置的密钥字母,模 26:

H E L L O
明文 7 4 11 11 14
密钥 X M C K L 23 12 2 10 11
和 mod 26 4 16 13 21 25
密文 E Q N V Z

解密就是减回去。电脑上通常用二进制,"加"就是异或(XOR)。

1.2 为什么破解不了

拿到密文 EQNVZ 的人,可以尝试任何一个 5 字母的密钥:

每个 5 字母的单词都对应恰好一个密钥。密钥是完全随机选的,所以每种明文都同样可能。攻击者算力再强也没用:问题不是"算不出来",而是"答案根本不确定"。

1.3 三个条件缺一不可

  1. 真随机:不能是伪随机数,否则攻击者可以去破解生成器;
  2. 和消息一样长:密钥不能循环使用;
  3. 只用一次:用两次就会崩溃(见 2.2 和 3.4 节)。

第二层:实际用处

2.1 真实使用

2.2 Venona 计划:用了两次就完了

二战期间,苏联因为战时生产压力,重复印制了一部分密码本页。美国陆军的 Venona 计划(1943–1980)利用这些重复使用的密钥,破译了数千条苏联情报电报,揭露了曼哈顿计划中的间谍(如 Klaus Fuchs、Rosenberg 夫妇)。

2.3 为什么现代加密不用它

问题 说明
密钥太长 加密 1 GB 视频需要 1 GB 真随机密钥,而且要事先安全地送到对方手上
密钥分发 如果有办法安全送出 1 GB 密钥,那为什么不直接送消息?
只保密,不防篡改 攻击者把密文某位翻转,明文对应位也被翻转(可延展性),而且不会被发现

所以现实中用流密码(ChaCha20、AES-CTR):用一把短密钥生成"看起来随机"的长密钥流,再异或。安全性从"信息论安全"降为"计算安全",换来了实用性。参见《LFSR与流密码》。

量子密钥分发(QKD)

QKD 的卖点就是"用物理定律安全地分发长密钥",再配合一次一密做到信息论安全。但它需要专用光纤或卫星,距离和速率都有限。


第三层:数学原理

3.1 完美保密的定义

香农的定义:对任意明文分布、任意明文 mm 和密文 cc,

Pr⁡[M=m∣C=c]=Pr⁡[M=m].\Pr[M = m \mid C = c] = \Pr[M = m].

看到密文前后,你对明文的判断完全没变。等价地,密文的分布与明文无关。

3.2 证明:群里的平移

设消息、密钥、密文都在一个有限群 (G,+)(G, +) 里(比如 Z26n\mathbb{Z}_{26}^n 或 F2n\mathbb{F}_2^n),密钥 KK 在 GG 上均匀随机,与 MM 独立,C=M+KC = M + K。

对任意 m,c∈Gm, c \in G,恰好有一个密钥 k=c−mk = c - m 使 m+k=cm + k = c。因此

Pr⁡[C=c∣M=m]=Pr⁡[K=c−m]=1∣G∣,\Pr[C = c \mid M = m] = \Pr[K = c - m] = \frac{1}{|G|},

与 mm 无关。由贝叶斯公式即得完美保密。

用抽象代数的话说:对每个固定的 mm,平移 k↦m+kk \mapsto m + k 是 GG 到自身的双射,均匀分布在双射下仍是均匀分布。

这个证明对任何有限群都成立,Shamir秘密分享的"k−1k-1 份毫无信息"本质上是同一个论证。

3.3 密钥至少和消息一样长

香农还证明:完美保密要求密钥空间 ∣K∣≥∣M∣|\mathcal{K}| \ge |\mathcal{M}|。

理由:固定一个可能出现的密文 cc。如果密钥比明文少,那么用所有密钥去解 cc,最多得到 ∣K∣<∣M∣|\mathcal{K}| < |\mathcal{M}| 个不同明文,于是某个明文 mm 永远不可能对应 cc,即 Pr⁡[M=m∣C=c]=0≠Pr⁡[M=m]\Pr[M = m \mid C = c] = 0 \neq \Pr[M = m]。

所以"短密钥 + 完美保密"是不可能的,这是信息论层面的定理,不是工程上还没做到。

3.4 手算例子:两次一密

同一个密钥加密两条消息

密钥 k=10110001k = 10110001。

  • m1=11001010m_1 = 11001010,c1=m1⊕k=01111011c_1 = m_1 \oplus k = 01111011
  • m2=01100110m_2 = 01100110,c2=m2⊕k=11010111c_2 = m_2 \oplus k = 11010111

攻击者把两个密文异或: c1⊕c2=10101100=m1⊕m2.c_1 \oplus c_2 = 10101100 = m_1 \oplus m_2.

密钥被消掉了(因为 k⊕k=0k \oplus k = 0)。攻击者得到两条明文的异或,对自然语言来说,这几乎等于直接读到了明文:猜测其中一条里的常见词("the"、"天气"),另一条对应位置就自动解出来,这叫 crib dragging。Venona 计划就是这么做的。(已用 Python 验算。)


总结

层次 要点
直觉 每种明文都有一个密钥对应,所以"什么都可能"
代数 群中加上均匀随机元素,结果仍均匀随机
代价 密钥 ≥\ge 消息长度(香农定理);只能用一次
现实 用流密码换取实用性;两次一密曾导致 Venona 破译