密码学补完计划 · 古典密码篇
本文档为社团内部学习资料,系统讲解密码学相关内容。
1. 古典密码概述
1.1 定义
古典密码是指计算机出现之前使用的密码技术,主要分为两大类: - 替代密码:将明文中的字符替换为其他字符 - 换位密码:重新排列明文中的字符顺序
1.2 发展历程
| 时期 | 密码 | 特点 |
|---|---|---|
| 古罗马 | 凯撒密码 | 最早的移位密码 |
| 中世纪 | 简单替换密码 | 字母表随机映射 |
| 文艺复兴 | 维吉尼亚密码 | 多表替代,破解难度提升 |
| 19世纪 | 维吉尼亚破解 | 巴贝奇、卡西斯基发现破解方法 |
| 二战 | 恩尼格玛 | 机械密码机,多表替代的终极形态 |
1.3 古典密码 vs 现代密码
| 维度 | 古典密码 | 现代密码 |
|---|---|---|
| 密钥长度 | 短(几字节到几十字节) | 长(128位以上) |
| 安全性 | 可被手工或简单程序破解 | 依赖数学难题 |
| 实现方式 | 手工、简单机械 | 计算机算法 |
| 应用 | 军事、外交 | 互联网安全、区块链等 |
2. 单表替代密码
单表替代密码是指使用固定的映射关系将明文字母替换为密文字母。
2.1 凯撒密码
原理
- 将字母表循环移位固定位数
- 密钥:移位量k(1-25)
加密公式
C = (P + k) mod 26
其中P为明文数字(A=0),C为密文数字
解密公式
P = (C - k) mod 26
示例
明文: HELLO
移位3: KHOOR
移位13: URYYB (ROT13)
识别特征
- 密文保持字母结构(单词长度不变)
- 词频分布与英文相同,只是整体偏移
- 暴力破解只需尝试25次
变种:ROT家族
| 变种 | 适用范围 | 示例 |
|---|---|---|
| ROT5 | 数字0-9 | 0→5, 1→6, ..., 9→4 |
| ROT13 | 字母A-Z | 最常用,加密两次恢复原文 |
| ROT18 | 字母+数字 | ROT13+ROT5 |
| ROT47 | ASCII 33-126 | 对可打印字符进行47位移位 |
ROT13示例
原文: HELLO
ROT13: URYYB
再次ROT13: HELLO
2.2 Atbash密码
原理
- 字母表对称映射:A↔Z, B↔Y, C↔X, ...
- 公式:
C = 25 - P(A=0, Z=25)
映射表
A B C D E F G H I J K L M
Z Y X W V U T S R Q P O N
示例
明文: HELLO
映射: H(7) ↔ S(18), E(4) ↔ V(21), L(11) ↔ O(14)
结果: SVOOL
识别特征
- 字母映射是对称的
- 解密方法同加密方法
- 常见于简单谜题和CTF签到题
2.3 简单替换密码
原理
- 建立字母表的一对一随机映射
- 密钥空间:26! ≈ 2^88(约288位)
示例
明文字母: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
密文字母: Q W E R T Y U I O P A S D F G H J K L Z X C V B N M
明文"HELLO" → 密文"I T P P A"(根据映射)
识别特征
- 密文字母频率分布与英文相同,但字母对应关系改变
- 单词长度模式保留
- 可通过频率分析破解
破解方法
- 频率分析:英文中E、T、A出现频率最高
- 常见单词:寻找"the"、"and"等常见词
- 字母组合:分析常见双字母组(th、he、in等)
2.4 仿射密码
原理
-
凯撒密码的扩展,使用线性变换
-
加密公式:
\(C = (a \times P + b) \pmod{26}\)
- 解密公式:
\(P = a^{-1} \times (C - b) \pmod{26}\)
参数要求
- a 与 26 互质 \(\gcd(a, 26) = 1\)
- a 的取值:1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25(共12种)
- b 取值:0-25(26种)
- 密钥空间:12 × 26 = 312
示例
取 a=5, b=8
明文 A(0): (0×5+8) mod 26 = 8 → I
明文 B(1): (1×5+8) mod 26 = 13 → N
明文 C(2): (2×5+8) mod 26 = 18 → S
识别特征
- 字母映射有数学规律(不是完全随机)
- 密文字母分布可能呈现周期性
- 可通过求解线性方程破解
破解方法
- 找到两个字母的对应关系,列方程求解
- 暴力尝试所有312种组合
2.5 键盘布局密码
原理
- 利用键盘布局进行映射
- 常见类型:
- QWERTY移位:每个字母替换为相邻键
- 键盘行列映射:按键盘行列重新编码
QWERTY移位示例
原键盘:
Q W E R T Y U I O P
A S D F G H J K L
Z X C V B N M
右移一位:
W E R T Y U I O P [
S D F G H J K L ;
X C V B N M ,
明文: HELLO
H → J (右移)
E → R
L → ;
L → ;
O → P
结果: JR;;P
识别特征
- 密文看起来像随机字母,但实际是键盘相邻键
- 常见于CTF简单题和趣味密码
变种
- 上下移位:H→Y, E→D
- 对角线移位:Q→A, A→Z
- 键盘倒序:Q↔P, W↔O
3. 多表替代密码
多表替代密码使用多个替换表,根据密钥选择不同的映射,抵抗频率分析。
3.1 维吉尼亚密码
原理
- 使用关键词,每个位置使用不同的凯撒移位
- 移位量由密钥字母决定(A=0, B=1, ..., Z=25)
加密公式
其中\(K_i\)为密钥字母对应的数字
维吉尼亚方阵
| A | B | C | ... | Z | |
|---|---|---|---|---|---|
| A | A | B | C | ... | Z |
| B | B | C | D | ... | A |
| C | C | D | E | ... | B |
| ... | ... | ... | ... | ... | ... |
| Z | Z | A | B | ... | Y |
加密示例
明文: ATTACKATDAWN
密钥: LEMONLEMONLE
数字转换:
明文: 0 19 19 0 2 10 0 19 3 0 22 13
密钥: 11 4 12 14 13 11 4 12 14 13 11 4
密文: 11 23 5 14 15 21 4 5 17 13 7 17
字母: L X F O P V E F R N H R
结果: LXFO PVE FRN HR (去掉空格: LXFOPVEFRNHR)
解密示例
密文: L X F O P V E F R N H R
密钥: L E M O N L E M O N L E
计算: (密文数字 - 密钥数字) mod 26
L(11)-L(11)=0→A
X(23)-E(4)=19→T
F(5)-M(12)=-7 mod 26=19→T
...
结果: ATTACKATDAWN
识别特征
- 相同明文可能对应不同密文(消除单表替代的频率特征)
- 密文整体字母频率分布更均匀
- 存在周期性重复模式
破解方法
- Kasiski测试:寻找重复的密文片段,推测密钥长度
- 重合指数:计算不同偏移下的重合指数,找出密钥长度
- 确定密钥长度后:将密文按密钥长度分组,每组独立进行频率分析破解凯撒
3.2 博福特密码
原理
-
维吉尼亚密码的变种
-
加密公式:
$\(C_i = (K_i - P_i) \mod{26}\)$
- 解密公式:(加密和解密相同)
$\(P_i = (K_i - C_i) \mod{26}\)$
示例
明文: ATTACKATDAWN
密钥: LEMONLEMONLE
计算:
K(11)-A(0)=11→L
K(4)-T(19)=4-19=-15 mod 26=11→L
...
结果: L L ... (与维吉尼亚不同)
特点
- 加密和解密过程相同
- 使用与维吉尼亚相同的方阵,但查找方式不同
3.3 滚动密钥密码
原理
- 维吉尼亚密码的变种
- 密钥与明文等长,通常是一段文本
示例
明文: ATTACKATDAWN
密钥: THEENEMYISWATCHING (从某本书中选取)
加密: 使用维吉尼亚规则
特点
- 理论上更安全(无密钥重复)
- 实际使用中密钥可能被猜测(如常见书籍)
3.4 自动密钥密码
原理
- 维吉尼亚密码的变种
- 密钥 = 初始密钥 + 明文本身(或密文本身)
两种变体
- 明文字典式:密钥 = 初始密钥 + 明文
- 密文字典式:密钥 = 初始密钥 + 密文
示例(明文自动密钥)
明文: ATTACKATDAWN
初始密钥: LEMON
实际密钥: LEMONATTACKATDA (密钥=初始密钥+明文)
加密: 使用维吉尼亚规则
4. 换位密码
换位密码不改变字母本身,只改变字母的顺序。
4.1 栅栏密码
原理
- 将明文按一定宽度写成多行,再按列读取
普通栅栏(2栏)
明文: HELLOWORLD
2行:
H L O O L
E L W R D
按行读取: HLOOL ELWRD
密文: HLOOLELWRD
示例2(3栏)
明文: HELLOWORLD
3行:
H L O D
E O R
L W L
按行读取: H L O D E O R L W L
密文: WLODEORLWL
W型栅栏(曲径密码)
- 按波浪形写入,再按行读取
明文: HELLOWORLD
W型排列(3行):
行1: H . . . O . . . L . . . (H, O, L)
行2: . E . L . W . R . D . (E, W, R, D)
行3: . . L . . . O . . . . (L, O)
按行读取: H O L E W R D L O
结果: HOL EWR DLO (HOL EWRDLO)
识别特征
- 字母频率与明文相同(只是顺序改变)
- 密文长度与明文相同
- 常见于CTF签到题
破解方法
- 暴力尝试所有可能的栏数和排列方式
4.2 列换位密码
原理
- 将明文按行写入矩阵,再按列读取
- 列的顺序由密钥决定
示例
明文: WE ARE DISCOVERED FLEE AT ONCE
去除空格: WEAREDISCOVEREDFLEEATONCE
密钥: 4 3 1 2 (表示列的顺序)
写入矩阵(6行4列):
W E A R
E D I S
C O V E
R E D F
L E E A
T O N C
按密钥列顺序读取:
密钥1列(第3列): A I V D E N → AIVDEN
密钥2列(第4列): R S E F A C → RSEFAC
密钥3列(第1列): W E C R L T → WECRLT
密钥4列(第2列): E D O E E O → EDOEEO
结果: AIVDENRSEFACWECRLTEDOEEO
识别特征
- 密文长度与明文相同
- 解密需要知道密钥(列的顺序)
- 可通过分析列数猜测
4.3 螺旋密码
原理
- 将明文按螺旋顺序写入矩阵,再按行读取(或相反)
示例
明文: H E L L O W O R L D A B
正确示例:12字母,4行3列
明文: HELLOWORLDAB (12字母)
矩阵: 4行 × 3列 = 12格
螺旋路径(从(0,0)开始,向右 → 向下 → 向左 → 向上 → 向右...)
填充顺序:
位置1: (0,0) ← H
位置2: (0,1) ← E
位置3: (0,2) ← L
位置4: (1,2) ← L
位置5: (2,2) ← O
位置6: (3,2) ← W
位置7: (3,1) ← O
位置8: (3,0) ← R
位置9: (2,0) ← L
位置10: (1,0) ← D
位置11: (1,1) ← A
位置12: (2,1) ← B
填充结果矩阵:
行0: H E L
行1: D A L
行2: L B O
行3: R O W
行0: H E L
行1: D A L
行2: L B O
行3: R O W
密文: HELDALLBOROW
识别特征
- 密文长度与明文相同
- 需要知道矩阵大小和螺旋方向
5. 其他古典密码
5.1 波利比乌斯方阵
原理
- 使用5×5网格(I和J合并)
- 每个字母用行号和列号表示(两位数字)
方阵
1 2 3 4 5
1 A B C D E
2 F G H I/J K
3 L M N O P
4 Q R S T U
5 V W X Y Z
示例
明文: HELLO
H: 2 3
E: 1 5
L: 3 1
L: 3 1
O: 3 4
结果: 23 15 31 31 34
识别特征
- 密文是两位数字组合
- 数字范围1-5
- 常见于CTF和密室逃脱
变种
- 使用6×6方阵(包含数字)
- 使用不同顺序的字母排列
5.2 阿伯哈姆密码
原理
- 波利比乌斯方阵的变种
- 使用特定关键词填充方阵
示例
关键词: CIPHER
填充方阵(去重后按字母序排列):
C I P H E R A B D F G K L M N O Q S T U V W X Y Z
排列成5×5:
C I P H E
R A B D F
G K L M N
O Q S T U
V W X Y Z
(I/J合并)
5.3 跳舞的小人
背景
- 柯南·道尔《福尔摩斯探案集》中的密码
- 使用不同姿势的小人代表字母
原理
- 每个小人姿势对应一个字母
- 旗帜表示单词结束
识别特征
- 图形符号,小人姿势
- 常见于CTF图片隐写题
6. 古典密码的破解方法
6.1 频率分析
英文单字母频率
E: 12.7% T: 9.1% A: 8.2% O: 7.5% I: 7.0%
N: 6.7% S: 6.3% H: 6.1% R: 6.0% D: 4.3%
L: 4.0% C: 2.8% U: 2.8% M: 2.4% W: 2.4%
F: 2.2% G: 2.0% Y: 2.0% P: 1.9% B: 1.5%
V: 1.0% K: 0.8% J: 0.2% X: 0.2% Q: 0.1%
Z: 0.1%
英文双字母组频率
th: 3.9% he: 3.2% in: 2.4% er: 2.1% an: 1.9%
re: 1.8% nd: 1.8% on: 1.7% en: 1.6% at: 1.5%
英文三字母组频率
the: 5.1% and: 2.1% ing: 1.8% her: 1.3% hat: 0.9%
破解步骤
- 统计密文字母频率
- 与英文频率对比,猜测E、T等高频字母的对应关系
- 寻找常见单词(如"the"),验证猜测
- 逐步替换,形成可读文本
6.2 重合指数
定义
- 随机选取两个字母,它们相同的概率
- 英文重合指数:约0.065(I = Σ(n_i(n_i-1)) / (N(N-1)))
用途
- 判断密文是否为英文
- 推测维吉尼亚密码的密钥长度
计算方法
I = Σ [f_i × (f_i - 1)] / [N × (N - 1)]
其中f_i为字母i的频率,N为总字母数
破解维吉尼亚的应用
- 假设密钥长度为L
- 将密文分成L组
- 计算每组的重合指数
- 如果某组重合指数接近0.065,则该分组可能是正确的
6.3 Kasiski测试
原理
- 寻找密文中重复的片段
- 重复片段之间的距离可能是密钥长度的倍数
步骤
- 找出所有重复的3-4字母片段
- 记录片段之间的距离
- 计算这些距离的最大公约数
- GCD很可能就是密钥长度
示例
密文中出现重复片段"VHX":
位置: 15, 45, 75
距离: 30, 30
GCD: 30
密钥长度可能是30的因数(如15, 10, 6, 5, 3, 2, 1)
6.4 暴力破解
适用范围
- 密钥空间较小的密码(凯撒、仿射、简单栅栏等)
凯撒暴力破解
for shift in range(1, 26):
decrypted = apply_shift(ciphertext, -shift)
if is_english(decrypted):
print(f"Shift {shift}: {decrypted}")
仿射暴力破解
for a in [1,3,5,7,9,11,15,17,19,21,23,25]:
for b in range(26):
decrypted = affine_decrypt(ciphertext, a, b)
if is_english(decrypted):
print(f"a={a}, b={b}: {decrypted}")
7. CTF中的古典密码
7.1 常见题型
| 题型 | 描述 | 难度 |
|---|---|---|
| 签到题 | 直接解码凯撒、Base64等 | ⭐ |
| 多重编码 | 多层嵌套,需要逐层解码 | ⭐⭐ |
| 混合密码 | 多种古典密码组合 | ⭐⭐⭐ |
| 带提示题 | 提示密钥或关键信息 | ⭐⭐ |
| 无提示题 | 需要频率分析等手段 | ⭐⭐⭐⭐ |
7.2 解题思路
- 识别密码类型
- 观察密文特征(字母、数字、符号)
- 尝试常见编码和密码
- 尝试简单破解
- 凯撒:暴力破解
- 栅栏:尝试不同栏数
- Base系列:直接解码
- 频率分析
- 统计字母频率
- 与英文频率对比
- 猜测常见单词
- 工具辅助
- 使用CyberChef的Magic功能
- 多层嵌套
- 先解码外层
- 重复直到得到可读文本
7.3 工具推荐
| 工具 | 用途 | 特点 |
|---|---|---|
| CyberChef | 通用加解密 | 支持所有古典密码,可视化操作 |
| Ciphey | 自动化解密 | 支持50+种编码/密码 |
| dCode | 在线工具集 | 分类详细,每种密码都有单独页面 |
| Python | 自定义脚本 | 灵活处理特殊需求 |
7.4 Python脚本示例
凯撒暴力破解
def caesar_bruteforce(ciphertext):
for shift in range(26):
plaintext = ''
for c in ciphertext:
if c.isalpha():
base = ord('A') if c.isupper() else ord('a')
plaintext += chr((ord(c) - base - shift) % 26 + base)
else:
plaintext += c
print(f"Shift {shift}: {plaintext}")
维吉尼亚解密
def vigenere_decrypt(ciphertext, key):
plaintext = ''
key_len = len(key)
for i, c in enumerate(ciphertext):
if c.isalpha():
base = ord('A') if c.isupper() else ord('a')
shift = ord(key[i % key_len].upper()) - ord('A')
plaintext += chr((ord(c) - base - shift) % 26 + base)
else:
plaintext += c
return plaintext
频率分析辅助
from collections import Counter
def frequency_analysis(text):
text = ''.join([c for c in text if c.isalpha()]).upper()
counter = Counter(text)
total = len(text)
freq = {c: count/total for c, count in counter.items()}
sorted_freq = sorted(freq.items(), key=lambda x: x[1], reverse=True)
return sorted_freq
8. 练习
基础题
-
凯撒密码
WKH TXLFN EURZQ IRA MXPSV RYHU WKH ODCB GRJ -
ROT13
GUR DHVPX OEBJA SBK WHZCF BIRE GUR YNML QBT -
Atbash
GSV RH Z YIRFOS GSRM ZMW SZIB -
栅栏密码(2栏)
HLELOWRLO -
仿射密码
已知 a=5, b=8,解密: F X O K -
简单替换密码
Lzw lwvwd sgd izx lwvwd bjzr (提示:词频分析) -
维吉尼亚密码
密文: Fmiv eohvi wt xivm 密钥: KEY -
波利比乌斯方阵
23 15 31 31 34 15 44 15 34 53 34 -
多层嵌套
Uryyb, jbeyq! Gur xrl vf: cvcr提示:先ROT13,再凯撒,得到一句话 -
混合密码
密文:RVOL TZRI BLFI 提示:先Atbash,再栅栏(2栏)
答案
THE QUICK BROWN FOX JUMPS OVER THE LAZY DOGTHE QUICK BROWN FOX JUMPS OVER THE LAZY DOGTHE IS A BRILLIANT THING AND HAZYHELLOWORLDHELLOThe secret key is the same key(示例)KEEP YOUR FRIENDS CLOSEHELLOWORLD(需合并I/J)Hello, world! The key is: pipeTHIS IS A TEST(示例)