2. 古典密码学(一):凯撒密码、单表替换密码的原理、实现与破解方法
古典密码学是现代密码学的基石,尽管其安全性在当今计算能力下已不堪一击,但其中蕴含的置换与替换思想,至今仍是许多现代密码算法的核心组件。本章将深入剖析两种最具代表性的古典密码:凯撒密码与单表替换密码,从原理、数学表示、编程实现到经典破解方法,建立对密码分析的基本认知。
2.1 凯撒密码:最简单的移位替换
凯撒密码(Caesar Cipher)是已知最古老的加密技术之一,由古罗马统帅尤利乌斯·凯撒使用。其核心思想是将明文中的每个字母在字母表上向后(或向前)移动一个固定的位数。
2.1.1 数学定义与密钥空间
设字母表为 A-Z(共26个字母),将字母映射为数字 0-25。加密与解密过程可表示为:
| 操作 | 公式 | 说明 |
|---|---|---|
| 加密 | E(p) = (p + k) mod 26 |
p 为明文数字,k 为密钥(移位量) |
| 解密 | D(c) = (c - k) mod 26 |
c 为密文数字 |
密钥空间:由于 k 的取值范围为 0-25,且 k=0 无实际加密效果,有效密钥空间仅为 25 种可能。这使得暴力破解(Brute Force)在手工条件下即可完成。
2.1.2 凯撒密码加密流程
下图展示了凯撒密码从明文输入到密文输出的完整流程,其中密钥 k=3(即经典凯撒移位):
2.1.3 Python 实现示例
def caesar_encrypt(plaintext: str, key: int) -> str:
"""凯撒密码加密"""
ciphertext = []
for char in plaintext.upper():
if char.isalpha():
shifted = (ord(char) - ord('A') + key) % 26
ciphertext.append(chr(shifted + ord('A')))
else:
ciphertext.append(char)
return ''.join(ciphertext)
def caesar_decrypt(ciphertext: str, key: int) -> str:
"""凯撒密码解密"""
return caesar_encrypt(ciphertext, -key)
# 示例
plain = "HELLO"
key = 3
cipher = caesar_encrypt(plain, key)
print(f"明文: {plain} → 密文: {cipher}") # 输出: KHOOR
print(f"解密: {caesar_decrypt(cipher, key)}") # 输出: HELLO
2.2 单表替换密码:更通用的替换体系
凯撒密码是单表替换密码的一个特例。在更一般的单表替换密码(Monoalphabetic Substitution Cipher)中,明文字母表中的每个字母被唯一且固定地映射到密文字母表中的一个字母,但映射关系不再局限于循环移位,而是任意的一一对应关系。
2.2.1 密钥空间与安全性
单表替换密码的密钥本质上是一个26个字母的排列。其密钥空间大小为:
26! = 26 × 25 × 24 × … × 1 ≈ 4.03 × 10²⁶
这个数字远大于凯撒密码的25种可能,理论上使得暴力破解变得不可行。然而,这并不意味着它是安全的。
| 对比维度 | 凯撒密码 | 单表替换密码 |
|---|---|---|
| 密钥形式 | 一个整数(移位量) | 一个完整的字母排列表 |
| 密钥空间 | 25 | ≈ 4 × 10²⁶ |
| 映射关系 | 循环移位,有规律 | 任意一一映射,无规律 |
| 抗暴力破解 | 极弱(手工可穷举) | 理论强(但存在其他攻击) |
| 抗频率分析 | 弱(保留字母频率分布) | 弱(保留字母频率分布) |
2.2.2 单表替换密码的加密流程
下图展示了单表替换密码的核心机制——通过一个随机生成的替换表(密钥)将明文映射为密文:
2.3 破解方法:从暴力破解到频率分析
2.3.1 凯撒密码的暴力破解
由于凯撒密码的密钥空间仅为25,我们可以尝试所有可能的密钥,并观察哪个结果看起来像有意义的英文文本。
破解步骤:
- 获取密文。
- 对
k = 1到25,依次执行解密。 - 检查每个解密结果中是否包含常见的英文单词(如
THE,AND,IS等)。 - 一旦发现可读文本,即找到正确密钥。
def caesar_brute_force(ciphertext: str):
"""凯撒密码暴力破解"""
print("尝试所有可能的密钥:")
for key in range(1, 26):
decrypted = caesar_decrypt(ciphertext, key)
print(f"k={key:2d}: {decrypted}")
# 示例:破解密文 "KHOOR"
caesar_brute_force("KHOOR")
# 输出中 k=3 时得到 "HELLO",即为正确结果
2.3.2 单表替换密码的频率分析
单表替换密码虽然密钥空间巨大,但有一个致命弱点:它没有改变字母在语言中的统计分布特征。在英文中,字母 E 的出现频率约为12.7%,远高于其他字母。这种统计规律在密文中被完整保留。
频率分析破解流程:
| 步骤 | 操作 | 说明 |
|---|---|---|
| 1 | 统计密文字母频率 | 计算每个字母在密文中出现的次数和百分比 |
| 2 | 排序并对比标准频率 | 将密文字母按频率降序排列,与英文标准频率表(E, T, A, O, I, N, S, H, R, ...)对比 |
| 3 | 假设映射关系 | 假设密文最高频字母对应明文 E,次高频对应 T,以此类推 |
| 4 | 部分解密与验证 | 应用假设的映射关系进行部分解密,观察是否出现有意义的单词片段 |
| 5 | 迭代修正 | 根据上下文和常见单词模式(如 TH, HE, ING)调整映射关系 |
| 6 | 完全恢复 | 重复步骤4-5,直到所有字母映射被正确还原 |
实用技巧:除了单字母频率,还可以利用以下统计特征辅助破解:
- 双字母组(Digrams):
TH,HE,IN,ER是最常见的组合。 - 三字母组(Trigrams):
THE,AND,ING,ION出现频率极高。 - 单词边界: 单字母单词只可能是
A或I。 - 常见词尾:
-ING,-ED,-TION,-S等。
2.3.3 频率分析破解示例
假设我们截获了一段密文(已去除空格):
密文: XMZ YMNX YMJ XMZ YMNX YMJ XMZ YMNX
步骤1:统计频率
密文中 X 出现3次,M 出现3次,Z 出现1次,Y 出现3次,N 出现3次,J 出现3次。
步骤2:假设映射
假设最高频字母 X, M, Y, N, J 对应 E, T, A, O, I 等。尝试将 X→E, M→T:
部分解密: E?Z ET?E E?Z ET?E E?Z ET?E
步骤3:模式识别
观察 E?Z 模式,结合常见三字母词 THE,推测 ?→H,即 Z→H。代入后得到:
部分解密: THE ETH THE ETH THE ETH
步骤4:完全恢复
进一步观察 ETH,推测为 AND 或 FOR 等。结合上下文,最终可确定完整映射关系,恢复明文为 THE AND THE AND THE AND。
重要警示:单表替换密码在现代计算环境下一文不值。自动化频率分析工具可以在毫秒级内破解任意长度的单表替换密文。切勿在实际安全场景中使用此类密码保护敏感信息。
2.4 本章小结
凯撒密码和单表替换密码作为古典密码学的代表,揭示了密码学中两个核心概念:
- 替换(Substitution): 用密文字母替换明文字母,是密码变换的基本操作之一。
- 密钥空间与安全性: 大的密钥空间是安全的必要条件,但绝非充分条件。单表替换密码拥有巨大的密钥空间,却因保留语言统计特征而被轻易攻破。
理解这些古典密码的弱点,是学习更安全密码体系(如多表替换、分组密码)的重要前提。