news 2026/8/7 5:00:02

古典密码入门:从凯撒到维吉尼亚,手把手实现与破解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
古典密码入门:从凯撒到维吉尼亚,手把手实现与破解

1. 项目概述:从“天书”到“游戏”,古典密码的魅力与基石

如果你对《达芬奇密码》里那些神秘的符号着迷,或者玩过《刺客信条》里用密码筒传递信息的桥段,甚至只是小时候和同桌传纸条时用过“字母移位”的暗号,那么,你已经在不经意间触碰到了“古典密码”的世界。这听起来像是个尘封在历史课本里的名词,似乎只属于凯撒、玛丽女王或者二战时期的谍报人员。但事实上,它远非故纸堆里的古董。古典密码是现代密码学的“源代码”,是理解今天无处不在的加密技术(从你手机锁屏到网上支付)最直观、最有趣的起点。它用最朴素的方式,回答了信息安全最核心的问题:如何在不安全的信道上,传递只有特定人才能读懂的信息?

我把这个系列称为“古典密码(一)”,目的不是做枯燥的历史考据,而是带你亲手“造轮子”。我们将抛开复杂的数学公式和晦涩的术语,像几个世纪前的密码学家一样,仅用纸、笔,或者几行简单的代码,去构建、拆解这些经典的加密方案。你会发现,许多看似高深的安全思想,其雏形就蕴藏在这些简单而精巧的设计中。无论是作为编程入门的趣味项目,还是作为理解现代加密原理的思维训练,亦或是单纯满足对“秘密”的好奇心,这个系列都将提供一条清晰、可实操的路径。接下来,我们就从最著名、也最基础的那一个开始——凯撒密码。它简单到你可能一眼就看穿,但正是这种简单,让它成为我们剖析密码学核心要素的完美标本。

2. 核心原理拆解:替换与移位的艺术

古典密码虽然形式多样,但其核心思想可以归结为两种最基本的操作:替换移位。理解这两种操作,就拿到了解开大多数古典密码的钥匙。

2.1 替换:一对一的信息伪装

替换,顾名思义,就是将明文(原始信息)中的每个字符,按照某种固定的规则,替换成另一个字符。这个规则就是“密钥”。凯撒密码是替换的一种特例——等距移位替换。更一般的替换密码,其替换表可以是任意混乱的。

例如,我们可以定义这样一个替换表:

  • 明文:A B C D E F G ...
  • 密文:X Q K L M P O ...

这样,“HELLO”加密后就可能变成“KMPPB”。这种密码被称为单表替换密码。它的安全性完全依赖于那张替换表(密钥)的保密性。一旦对手通过频率分析(我们后面会详细讲)或其他手段猜出或获取了替换表,整个加密体系就崩溃了。

注意:单表替换密码有一个致命弱点:它保留了原始语言的统计特征。在英文中,字母‘E’的出现频率远高于‘Z’。在密文中,出现频率最高的那个字母,很可能就对应着明文中的‘E’。这是古典密码分析中最经典的攻击手段。

2.2 移位:结构化的位置变换

移位,也称为置换,它不改变字符本身,而是改变字符在文本中的位置。比如,我们可以将明文写成矩阵,然后按列或按某种路线读取,从而生成密文。

一个简单的例子是栅栏密码。假设明文是“IAMACUTECAT”,我们将其按高低交错写成两行:

I A A U E A T M C T C T

然后按行读取,得到密文:“IAAUEAT MCTCT”。解密时,只需知道栅栏数(这里是2),就能恢复原状。

移位密码破坏了明文的结构,但如果没有结合替换,明文词汇的轮廓可能依然模糊可见(特别是去除空格后)。更复杂的移位密码会定义更复杂的填充和读取路径。

2.3 凯撒密码:一个完美的教学案例

凯撒密码完美地融合了这两种思想(尽管以替换为主)。它的操作极其简单:将字母表中的每个字母向后(或向前)移动一个固定的位数。这个“固定的位数”就是密钥。

加密过程

  1. 确定密钥K(例如K=3)。
  2. 对于明文中的每个字母,找到其在字母表中的位置。
  3. 将位置加上K(移位操作)。
  4. 如果加后超过字母表范围(如Z后移3位),则折返到字母表开头(取模运算)。
  5. 输出新位置对应的字母(替换操作)。

用数学公式表示加密过程:C = (P + K) mod 26用数学公式表示解密过程:P = (C - K) mod 26其中,C代表密文字母,P代表明文字母,K代表密钥,mod 26表示对26取模(因为英文字母有26个)。

例如,密钥K=3时:

  • 明文 A(0) -> (0+3) mod 26 = 3 -> D
  • 明文 X(23) -> (23+3) mod 26 = 26 mod 26 = 0 -> A

所以“ATTACK”加密后成为“DWWDFN”。

实操心得:在手动计算或编程实现时,务必处理好大小写和非字母字符。一个健壮的实现应该保留非字母字符(如空格、标点)不变,并且保持原始的大小写。这看似是细节,但在实际应用中至关重要,否则加密后的文本会失去可读性甚至被破坏结构。

3. 从凯撒到维吉尼亚:加密强度的演进

如果密码学停留在凯撒密码,那秘密将无处遁形。因为凯撒密码的密钥空间太小了(只有25种可能的移位,排除移位0)。攻击者甚至不需要频率分析,穷举所有25种可能即可破解。密码学家们很快开始了改进之路。

3.1 仿射密码:为凯撒增加“乘法”因子

仿射密码可以看作是凯撒密码的升级版。它的加密公式变为:C = (a * P + b) mod 26这里有两个密钥:ab。其中b就是凯撒密码中的移位量,而a是一个乘数因子。

要求:为了使加密过程可逆(即每个明文字母唯一对应一个密文字母,且反之亦然),a必须与26互质(即最大公约数gcd(a, 26) = 1)。满足这个条件的a有:1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25。共12个。

这样一来,密钥空间从凯撒的25个,扩大到了12 * 26 = 312个。虽然仍然很小,但已经无法用手工穷举了,必须借助频率分析。解密公式为:P = a^(-1) * (C - b) mod 26,其中a^(-1)a在模26下的乘法逆元。

3.2 维吉尼亚密码:对抗频率分析的里程碑

单表替换密码(包括凯撒、仿射)最大的敌人是频率分析。因为无论替换规则多复杂,一个明文字母总是被替换成同一个密文字母。维吉尼亚密码的革命性在于,它引入了多表替换的概念。

核心思想:使用一个关键词(Keyword)作为密钥,而不是一个简单的数字。加密时,根据关键词中每个字母的序号(A=0, B=1...)来决定对明文中对应字母使用哪个凯撒移位。

加密过程

  1. 确定关键词,例如“KEY”。
  2. 重复关键词,使其长度与明文一致:KEYKEYKEY...
  3. 对于明文第i个字母,找到关键词第i个字母对应的偏移量K_i(K=10, E=4, Y=24)。
  4. 使用偏移量K_i对明文第i个字母进行凯撒加密。

例如,用“KEY”加密“ATTACKATDAWN”:

明文: A T T A C K A T D A W N 密钥: K E Y K E Y K E Y K E Y 偏移:10 4 24 10 4 24 10 4 24 10 4 24 密文: K X R K G O K X R K A L

维吉尼亚密码的威力:同一个明文字母(如‘A’),在不同位置可能被加密成不同的密文字母(第一次遇到‘A’用K加密成K,第二次用Y加密成Y)。这彻底打乱了原始语言的字母频率统计特征,使得简单的频率分析失效。在很长一段时间内,它被认为是“不可破译”的。

注意事项:维吉尼亚密码的安全性严重依赖于关键词的长度和随机性。如果关键词很短且与明文相关(如一个常见的单词),那么它可能通过卡西斯基试验被破解。该试验通过寻找密文中重复出现的片段,来推测关键词的长度。因此,理想的关键词应该是一个长度与明文相当、完全随机的字符序列。这引出了“一次一密”的概念,这是理论上绝对安全的密码,但密钥分发和管理极其困难。

4. 手工实现与编程模拟

理解原理最好的方式就是动手实现。我们分别用手工和Python代码来实践凯撒和维吉尼亚密码。

4.1 凯撒密码的Python实现

def caesar_cipher(text, shift, mode='encrypt'): """ 实现凯撒密码的加密和解密。 :param text: 输入文本 :param shift: 移位量 (0-25) :param mode: 'encrypt' 或 'decrypt' :return: 加密或解密后的文本 """ result = [] shift = shift % 26 if mode == 'decrypt': shift = -shift # 解密时反向移位 for char in text: if char.isupper(): # 对大写字母处理 shifted = chr((ord(char) - ord('A') + shift) % 26 + ord('A')) result.append(shifted) elif char.islower(): # 对小写字母处理 shifted = chr((ord(char) - ord('a') + shift) % 26 + ord('a')) result.append(shifted) else: # 非字母字符原样保留 result.append(char) return ''.join(result) # 示例 plaintext = "Hello, World! This is a test." key = 5 ciphertext = caesar_cipher(plaintext, key, 'encrypt') print(f"密文: {ciphertext}") decrypted_text = caesar_cipher(ciphertext, key, 'decrypt') print(f"解密后: {decrypted_text}")

代码解析

  • ord(char)获取字符的ASCII码。
  • ord(char) - ord('A')将大写字母映射到0-25的范围。
  • + shift进行移位。
  • % 26实现折返(模运算)。
  • + ord('A')映射回ASCII码的大写字母范围。
  • 对小写字母同理。保留非字母字符使文本结构完整。

4.2 维吉尼亚密码的Python实现

def vigenere_cipher(text, keyword, mode='encrypt'): """ 实现维吉尼亚密码的加密和解密。 :param text: 输入文本(仅处理字母) :param keyword: 关键词(仅字母) :param mode: 'encrypt' 或 'decrypt' :return: 加密或解密后的文本 """ result = [] keyword = keyword.upper() key_index = 0 for char in text: if char.isalpha(): # 计算当前密钥字母的偏移量 shift = ord(keyword[key_index % len(keyword)]) - ord('A') if mode == 'decrypt': shift = -shift base = ord('A') if char.isupper() else ord('a') shifted = chr((ord(char) - base + shift) % 26 + base) result.append(shifted) key_index += 1 # 仅当处理字母时,密钥索引才前进 else: result.append(char) return ''.join(result) # 示例 plaintext = "Attack at dawn!" keyword = "LEMON" ciphertext = vigenere_cipher(plaintext, keyword, 'encrypt') print(f"密文: {ciphertext}") decrypted_text = vigenere_cipher(ciphertext, keyword, 'decrypt') print(f"解密后: {decrypted_text}")

关键点

  • 密钥keyword被循环使用以匹配明文长度。
  • 仅对字母字符进行加密,保持标点和空格,这是实际应用的常见要求。
  • 加解密的核心区别在于shift的正负。

4.3 手工加密解密表(维吉尼亚表)

在计算机出现之前,密码员使用一种叫做“维吉尼亚方阵”的表格进行手工加解密。这是一个26x26的表格,第一行为明文字母,第一列为密钥字母,交叉点即为密文字母。制作和使用这个表格本身,就是理解多表替换的绝佳方式。你可以尝试用Excel或手画一个,体验一下“古典”的加密工作流程。

5. 古典密码的分析与破解实战

设计密码是为了保护信息,而分析密码则是为了理解其弱点。作为学习者,我们既要会“加密”,也要懂“破解”。这不仅能加深对原理的理解,更是安全思维的训练——知道如何攻击,才能更好地防御。

5.1 凯撒密码的破解:穷举与频率分析

对于凯撒密码,破解几乎是 trivial 的。

方法一:穷举攻击因为密钥只有25种可能(1-25),我们可以简单地尝试所有移位,然后肉眼观察哪一段结果是有意义的英文。这个过程可以瞬间由计算机完成。

方法二:频率分析攻击即使不知道是凯撒密码,单表替换密码都怕频率分析。步骤:

  1. 统计密文中各字母的出现频率。
  2. 将频率排序,与英文标准字母频率表(E, T, A, O, I, N, S, H, R, D, L, C, U...)进行匹配。
  3. 假设密文中出现频率最高的字母对应明文中的‘E’,据此推算偏移量。
  4. 用推算出的密钥解密,看是否产生有意义的文本。如果不通,尝试频率第二高的字母对应‘E’或‘T’。

例如,一段密文经统计,字母‘H’出现最多。假设‘H’对应‘E’,则偏移量 key = ord('H') - ord('E') = 3。用密钥3解密验证即可。

5.2 维吉尼亚密码的破解:卡西斯基试验与重合指数法

破解维吉尼亚密码的关键是确定关键词的长度。一旦长度m被确定,那么密文就可以被分解成m组,每组都是由同一个凯撒密钥加密的(即第一组全由关键词第一个字母加密,第二组全由关键词第二个字母加密...)。这样,每一组就退化成了一个单表替换密码,可以用频率分析分别破解。

第一步:卡西斯基试验推测关键词长度

  1. 在密文中寻找重复出现的、长度至少为3的字母序列。
  2. 记录这些重复序列之间的间隔距离。
  3. 计算这些间隔距离的最大公约数(GCD)。这个GCD很可能就是关键词的长度。

原理:密文中出现重复序列,通常是因为明文中相同的单词或短语,被关键词中相同的部分加密所致。它们之间的间隔,很可能是关键词长度的整数倍。

第二步:弗里德曼重合指数法验证长度重合指数(Index of Coincidence, IC)是一个更数学化的方法,用于衡量一段文本中字母分布的“不均匀性”。自然语言的IC值较高(英文约0.065),而完全随机文本的IC值接近0.0385。

  1. 假设关键词长度为m。
  2. 将密文按每m个字母分组(第1, m+1, 2m+1...字母为第一组;第2, m+2, 2m+2...为第二组,以此类推)。
  3. 分别计算每一组的IC值。
  4. 如果m猜对了,那么每一组都是单表替换加密的文本,其IC值应接近0.065。如果m猜错了,分组会把不同密钥加密的字母混在一起,文本更接近随机,IC值会接近0.0385。

第三步:对每组进行频率分析确定长度m后,我们就有了m组单表替换密文。对每一组独立进行频率分析(如5.1所述),即可猜出关键词的每一个字母,最终拼接出完整关键词。

实操心得:在实际破解中,卡西斯基试验和重合指数法通常结合使用。卡西斯基试验能给出几个可能的长度的候选(比如6, 12, 18),然后用重合指数法去验证哪一个最可能。这个过程现在可以用程序自动化,但手工走一遍流程,对于理解多表替换密码的脆弱性根源至关重要。你会发现,维吉尼亚密码的强度完全依赖于关键词的长度随机性。一个短且非随机的关键词,在分析面前不堪一击。

6. 古典密码的现代启示与局限

学习古典密码,绝不仅仅是为了怀旧。它们像化石一样,清晰地展现了密码学进化脉络中的关键节点,其蕴含的思想和暴露的弱点,至今仍在深刻地影响着现代密码学。

6.1 核心安全思想的萌芽

  1. 密钥的秘密性:凯撒密码表明,算法的完全公开(移位)并不影响安全,只要密钥(移位量)保密。这预演了现代密码学的柯克霍夫原则:密码系统的安全性应依赖于密钥的保密,而非算法的保密。
  2. 混淆与扩散:维吉尼亚密码通过多表替换,实现了初步的“混淆”(使密文和密钥之间的关系尽可能复杂)。虽然古典密码中“扩散”(使明文一位的变化影响密文多位)的概念不明显,但这种增加复杂度的思想是一脉相承的。
  3. 计算安全 vs. 理论安全:古典密码的破解,从穷举(凯撒)到需要频率分析(单表替换),再到需要更复杂分析(维吉尼亚),体现了安全性的提升依赖于增加攻击者的计算成本。这与现代密码学追求“计算上不可行”破解的理念一致。而“一次一密”展示了信息论安全的终极形态,但其不实用性也警示我们,安全必须在理论强度和实际可用性之间取得平衡。

6.2 古典密码为何被彻底淘汰?

尽管有上述思想贡献,但古典密码在现代计算面前已毫无招架之力:

  1. 密钥空间过小:即使像仿射密码有312个密钥,在计算机面前也是瞬间可穷举。
  2. 无法抵抗统计攻击:单表替换保留统计特征,维吉尼亚密码在确定周期后也退化为单表替换。现代密码(如AES)的设计目标之一就是让密文在统计上与随机序列无法区分。
  3. 缺乏完整性验证:古典密码只提供保密性,无法防止密文在传输中被篡改。接收方无法验证收到的消息是否与发送方发出的完全一致。现代密码学通过哈希函数和消息认证码来解决这个问题。
  4. 无法实现身份认证:古典密码系统通常假设通信双方共享一个秘密密钥(对称加密)。这无法解决“你是谁”的问题。在现代网络环境中,我们需要公钥密码学来实现数字签名和身份认证。

6.3 在何处还能见到它们的身影?

虽然不再用于严肃的保密通信,但古典密码并未消失:

  • 趣味谜题与游戏:逃脱密室、寻宝游戏、某些剧情游戏(如《荒野大镖客2》中的藏宝图)常使用古典密码作为谜题元素。
  • 教育启蒙:是理解密码学概念最直观的教具。
  • 低强度混淆:在某些无需高安全性的场合,如简单的游戏存档保护、防止信息被一眼看穿(而非防破解),可能被简单使用。但必须清醒认识到,这绝不等于安全

7. 常见问题与避坑指南

在实际动手实现和玩转古典密码的过程中,我踩过一些坑,也总结了一些技巧。

7.1 实现时的技术细节

问题1:加解密后大小写混乱或标点丢失。

  • 原因:在编程实现时,没有对非字母字符和大小写进行妥善处理。
  • 解决:在加密循环中,使用char.isupper()char.islower()进行判断,分别处理。对于非字母字符,直接追加到结果中。这是保持文本格式正确的关键。

问题2:维吉尼亚密码解密结果不对。

  • 原因1:关键词中包含非字母字符,或加解密时没有统一关键词的大小写。
  • 解决:在处理前,将关键词统一转换为大写(或小写)。并确保关键词只由字母组成。
  • 原因2:加密和解密时,对非字母字符(如空格)是否跳过处理逻辑不一致。如果加密时遇到空格跳过了(没有消耗密钥字母),而解密时没有跳过,就会导致密钥错位。
  • 解决:确保加解密算法中,只有处理字母字符时,才消耗密钥索引。这是维吉尼亚密码实现中最常见的错误。

问题3:手工使用维吉尼亚表速度慢且易错。

  • 技巧:可以记住一个快速心算规则:将明文和密钥字母视为数字(A=0, B=1...),密文数字 = (明文数字 + 密钥数字) mod 26。解密时,明文数字 = (密文数字 - 密钥数字) mod 26。负数时加26即可。这比查表快得多。

7.2 分析与破解时的误区

问题4:频率分析对短文本失效。

  • 原因:频率统计需要足够的样本量。如果密文太短(比如只有十几个单词),字母频率分布可能完全不符合标准分布,导致分析失败。
  • 解决:对于短密文,优先尝试穷举(凯撒)或结合语言上下文、常见单词(如“the”,“and”,“of”)进行猜测。不要迷信频率分析。

问题5:卡西斯基试验找不到重复序列。

  • 原因:可能关键词很长,或者明文本身重复片段少,或者重复片段恰好因为密钥不同而没有在密文中重复。
  • 解决:尝试寻找长度为2的重复序列。或者直接使用重合指数法,遍历可能的关键词长度(比如从2到20),计算分组后的平均IC值,选取最高的几个作为候选长度。

问题6:破解出的“明文”看起来像乱码,但部分单词可读。

  • 原因:这可能遇到了“伪破解”。特别是在尝试不同关键词长度时,可能会偶然得到一个分组,其频率分布偶然与英语接近,导致分析出一段似是而非的“关键词”。
  • 解决:用你推测出的关键词去解密整个密文,而不仅仅是看分组分析结果。真正的破解应该能产生通顺、有意义的全文。同时,检查不同分组分析出的“密钥字母”是否能够组成一个有意义的单词或短语(关键词本身可能有含义),这也是一个辅助判断。

7.3 安全认知的“坑”

最大的坑:认为古典密码“有用”。这是我必须强调的:绝对不要将古典密码用于任何需要真正保密的场合。无论是凯撒、维吉尼亚,还是更复杂的仿射、Playfair密码,在现代计算机和算法面前,都如同透明。它们只是玩具和教学工具。理解它们,是为了理解现代加密技术为何要设计得如此复杂,是为了培养一种基本的安全直觉。真正的应用,请使用经过全球密码学家多年公开检验的现代标准算法,如AES(对称加密)、RSA/ECC(非对称加密)等,并遵循正确的使用模式。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/7 4:58:49

Kubernetes清单文件编写与部署实战指南

1. Kubernetes清单文件基础认知Kubernetes清单文件(Manifest)是定义集群工作负载的核心配置文件,采用YAML或JSON格式编写。这份看似简单的文本文件实际上承载着Kubernetes声明式API的全部精髓——你只需要告诉系统"想要什么状态"&a…

作者头像 李华
网站建设 2026/8/7 4:57:34

Python数据分析实战:泰坦尼克号生存预测的探索性数据分析全流程

1. 项目概述:从泰坦尼克号到数据洞察“你能在泰坦尼克号上活下来吗?”——这不仅仅是一个引人入胜的历史假设,更是数据科学领域最经典的入门项目。它像一块试金石,让无数初学者通过Python和探索性数据分析(EDA&#xf…

作者头像 李华
网站建设 2026/8/7 4:56:40

实战化C++后台开发工具链:从编码到部署的全流程效率提升

1. 项目概述:为什么我们需要一个实战化的C后台开发工具链? 如果你是一名C后台开发者,或者正打算进入这个领域,你肯定不止一次地听过“工具链”这个词。它听起来有点庞大,甚至有些吓人,仿佛是一套复杂、笨重…

作者头像 李华
网站建设 2026/8/7 4:55:52

长上下文时代下,企业级RAG的工程化价值与实战优化

1. 项目概述:当大模型“记性”变好,RAG的价值何在?最近圈子里讨论得挺热闹,大家都在问:现在的大模型,动辄支持128K、200K甚至上百万的上下文长度,直接把一整本《三体》塞进去对话都绰绰有余。在…

作者头像 李华
网站建设 2026/8/7 4:55:50

WebNN实战指南:浏览器原生AI推理从入门到应用部署

1. 项目概述:当AI推理遇上浏览器作为一名在AI工程化和Web技术交叉领域摸爬滚打了多年的开发者,我经历过太多这样的场景:一个轻量级的图像分类或文本情感分析需求,却不得不拉起一个后端服务,部署模型,再通过…

作者头像 李华
网站建设 2026/8/7 4:55:23

STM32串口IAP固件升级实战:从HAL库实现到生产部署全解析

1. 项目缘起:为什么串口IAP依然是嵌入式开发的“硬通货”?最近在整理一个老项目的维护文档,发现一个挺有意思的现象:即便现在无线OTA(Over-The-Air)技术满天飞,但在很多工业控制、消费电子甚至是…

作者头像 李华