跳转至

密码学补完计划 · 古典密码篇

本文档为社团内部学习资料,系统讲解密码学相关内容。


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"(根据映射)

识别特征

  • 密文字母频率分布与英文相同,但字母对应关系改变
  • 单词长度模式保留
  • 可通过频率分析破解

破解方法

  1. 频率分析:英文中E、T、A出现频率最高
  2. 常见单词:寻找"the"、"and"等常见词
  3. 字母组合:分析常见双字母组(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

识别特征

  • 字母映射有数学规律(不是完全随机)
  • 密文字母分布可能呈现周期性
  • 可通过求解线性方程破解

破解方法

  1. 找到两个字母的对应关系,列方程求解
  2. 暴力尝试所有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)

加密公式

\[C_i = (P_i + K_i) \mod{26}\]

其中\(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

识别特征

  • 相同明文可能对应不同密文(消除单表替代的频率特征)
  • 密文整体字母频率分布更均匀
  • 存在周期性重复模式

破解方法

  1. Kasiski测试:寻找重复的密文片段,推测密钥长度
  2. 重合指数:计算不同偏移下的重合指数,找出密钥长度
  3. 确定密钥长度后:将密文按密钥长度分组,每组独立进行频率分析破解凯撒

维吉尼亚爆破网址

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 自动密钥密码

原理

  • 维吉尼亚密码的变种
  • 密钥 = 初始密钥 + 明文本身(或密文本身)

两种变体

  1. 明文字典式:密钥 = 初始密钥 + 明文
  2. 密文字典式:密钥 = 初始密钥 + 密文

示例(明文自动密钥)

明文: 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%

破解步骤

  1. 统计密文字母频率
  2. 与英文频率对比,猜测E、T等高频字母的对应关系
  3. 寻找常见单词(如"the"),验证猜测
  4. 逐步替换,形成可读文本

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为总字母数

破解维吉尼亚的应用

  1. 假设密钥长度为L
  2. 将密文分成L组
  3. 计算每组的重合指数
  4. 如果某组重合指数接近0.065,则该分组可能是正确的

6.3 Kasiski测试

原理

  • 寻找密文中重复的片段
  • 重复片段之间的距离可能是密钥长度的倍数

步骤

  1. 找出所有重复的3-4字母片段
  2. 记录片段之间的距离
  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 解题思路

  1. 识别密码类型
    • 观察密文特征(字母、数字、符号)
    • 尝试常见编码和密码
  2. 尝试简单破解
    • 凯撒:暴力破解
    • 栅栏:尝试不同栏数
    • Base系列:直接解码
  3. 频率分析
    • 统计字母频率
    • 与英文频率对比
    • 猜测常见单词
  4. 工具辅助
    • 使用CyberChef的Magic功能
  5. 多层嵌套
    • 先解码外层
    • 重复直到得到可读文本

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. 练习

基础题

  1. 凯撒密码 WKH TXLFN EURZQ IRA MXPSV RYHU WKH ODCB GRJ

  2. ROT13

    GUR DHVPX OEBJA SBK WHZCF BIRE GUR YNML QBT

  3. Atbash

    GSV RH Z YIRFOS GSRM ZMW SZIB

  4. 栅栏密码(2栏)

    HLELOWRLO

  5. 仿射密码 已知 a=5, b=8,解密: F X O K

  6. 简单替换密码 Lzw lwvwd sgd izx lwvwd bjzr (提示:词频分析)

  7. 维吉尼亚密码 密文: Fmiv eohvi wt xivm 密钥: KEY

  8. 波利比乌斯方阵 23 15 31 31 34 15 44 15 34 53 34

  9. 多层嵌套 Uryyb, jbeyq! Gur xrl vf: cvcr 提示:先ROT13,再凯撒,得到一句话

  10. 混合密码

    密文:RVOL TZRI BLFI 提示:先Atbash,再栅栏(2栏)

答案

  1. THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
  2. THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
  3. THE IS A BRILLIANT THING AND HAZY
  4. HELLOWORLD
  5. HELLO
  6. The secret key is the same key(示例)
  7. KEEP YOUR FRIENDS CLOSE
  8. HELLOWORLD(需合并I/J)
  9. Hello, world! The key is: pipe
  10. THIS IS A TEST(示例)