维吉尼亚密码

如何破解维吉尼亚密码:Kasiski 检验与密钥还原

学习如何在没有密钥的情况下,利用 Kasiski 检验、重合指数和卡方频率分析来破解维吉尼亚密码。

发布于 2026年3月18日
14 分钟阅读
密码学指南

三个多世纪以来,维吉尼亚密码被誉为 "le chiffre indéchiffrable"——"不可破译的密码"。其多表替换机制掩盖了字母频率规律,令单表替换密码(如凯撒密码)轻易可破的攻击方法统统失效。同一个明文字母会随位置不同加密成完全不同的密文字母,密码分析者无从利用这种变化。

1850 至 1860 年代,两项突破性发现彻底打破了这一神话。Charles Babbage 约于 1854 年秘密破解了这种密码,Friedrich Kasiski 则于 1863 年独立发表了通用攻击方法。他们的洞见简洁而优雅:重复使用的关键词在密文中产生周期性规律,这些规律可以被测量、分析并加以利用,无需看到原始明文即可还原密钥。

本文将带你完整走过维吉尼亚密码的密码分析全过程——从识别多表替换加密,到确定密钥长度,再到还原每一个密钥字母。无论你是在解 CTF 挑战、修密码学课程,还是只是好奇密码破译的原理,这些技术都能为你提供一套系统性的破解方法。

维吉尼亚密码为何被认为不可破译

要理解为何破解维吉尼亚密码需要全新的方法,首先需要了解它与更简单的替换密码有何不同。

凯撒密码中,每个字母按相同的量偏移。字母 E 是英语中出现频率最高的字母(约占 12.7%),在凯撒密码中只是移动到新位置。密码分析者只需查看密文的频率分布,找到峰值,就能立即确定偏移量。整个密钥空间只有 25 个可能值。

维吉尼亚密码通过使用重复关键词在每个位置改变偏移量,消除了这一弱点。如果关键词是"LEMON"(长度为 5),则第 1 位偏移 11(L),第 2 位偏移 4(E),第 3 位偏移 12(M),第 4 位偏移 14(O),第 5 位偏移 13(N)。第 6 位重新循环到偏移 11,如此反复。

结果是字母 E 不再对应唯一一个密文字母。根据与之对齐的关键词字母不同,E 可能变成 P、I、Q、S、R 或其他任意字母。密文的频率分布大幅扁平化——没有任何字母占主导地位——让秒破凯撒的直接频率分析变得毫无用处。

但"毫无用处"并不等于"完全不可能"。重复关键词引入了一个微妙的结构性弱点,Kasiski 与 Babbage 各自独立发现了利用它的方法。

识别维吉尼亚密文

在尝试破解密码之前,你需要判断是否确实面对的是维吉尼亚加密。以下几个特征可将其与其他密码类型区分开来:

  • 保留词边界的字母字符。 与凯撒密码一样,维吉尼亚密码传统上只对字母加密,保留空格和标点符号。词语长度与原始明文相同。
  • 扁平化但不均匀的字母分布。 凯撒密文的频率分布形如英语但整体偏移;维吉尼亚密文的分布则明显更平坦——没有单一字母占主导——但也并非完全均匀。完全均匀的频率才意味着一次性密码本或随机文本。
  • 重合指数介于 0.04 至 0.05 之间。 英语文本的重合指数约为 0.0667,真正随机文本的重合指数约为 0.0385。维吉尼亚密文通常落在两者之间,这一中间范围是多表替换的有力指标。
  • 在规律间隔出现的重复序列。 如果你发现相同的三字母或更长序列以相差某个公因数的距离出现,那么该文本很可能是维吉尼亚加密的。这一观察是 Kasiski 检验的基础。

如果你想自动化这一识别步骤,密码识别器工具会利用上述特征检测维吉尼亚加密并自动估算密钥长度。

两阶段攻击策略

破解维吉尼亚密码需要两阶段方法。这种划分是根本性的:该密码的安全性依赖于两个独立的秘密(密钥长度和密钥字母本身),每个都必须用不同的技术来攻击。

第一阶段: 利用 Kasiski 检验和/或重合指数分析确定密钥长度。

第二阶段: 一旦密钥长度已知,将密文分组,并利用频率分析还原每个密钥字母。

这种方法的优雅之处在于,它将破解多表替换密码的问题化简为多个破解简单凯撒密码的实例——而后者早在几百年前就已被解决。

第一阶段:确定密钥长度

方法 A:Kasiski 检验

该方法由已退役的普鲁士军官 Friedrich Kasiski 于 1863 年在其著作 Die Geheimschriften und die Dechiffrir-Kunst(《密写术与解密艺术》)中发表,利用了重复关键词的一个根本性后果。

核心洞见如下:常见明文序列——如"THE"、"AND"、"ING"、"TION"等词——偶尔会与重复关键词中的相同位置对齐。当这种情况发生时,相同的明文序列与相同的密钥字母加密,产生相同的密文序列。通过找到这些重复的密文序列并测量它们之间的距离,就可以确定密钥长度。

Kasiski 检验的示例

假设你正在分析一段密文,发现以下重复三字母组合:

出现次序序列位置到下次的距离
第 1 次VGH824
第 2 次VGH3224
第 3 次VGH56

重复之间的距离均为 24。密钥长度必然是这些距离的因数,因为关键词每 k 个字母重复一次,所以只有当两个相同明文序列的位置差是 k 的倍数时,才会产生相同的密文序列。

24 的因数为:1、2、3、4、6、8、12、24。

现假设你还发现了更多重复序列:

序列位置距离因数
VGH8, 32, 5624, 241, 2, 3, 4, 6, 8, 12, 24
QMR15, 33181, 2, 3, 6, 9, 18
BWLX42, 78361, 2, 3, 4, 6, 9, 12, 18, 36

三组距离的公因数是 6。这强烈提示关键词长度为 6 个字符。

Kasiski 检验的适用条件

Kasiski 分析的有效性在很大程度上取决于可用密文的数量:

  • 少于 100 个字符: 重复序列很少甚至根本不出现。Kasiski 分析在此长度下不可靠。
  • 100 至 200 个字符: 可能找到少量重复三字母组合,足以给出初步的密钥长度估计,但可能还不够确定。
  • 200 个字符以上: 该方法变得高度可靠。将出现多个重复序列,其距离将收敛到正确的密钥长度。
  • 1000 个字符以上: 分析几乎可以确定,大量重复三字母组合乃至四字母组合提供了压倒性的统计证据。

还需注意,密文中并非所有重复序列都有意义。有些重复是巧合——明文序列与不同关键词位置对齐,碰巧产生了相同的密文。这些误报会给分析引入噪声,这也是为什么需要检查多个重复序列并寻找最常见公因数的原因。

方法 B:重合指数(IC)

William Friedman 于 1920 年在为美国陆军信号情报局所做的开创性工作中提出了重合指数,提供了一种纯统计学方法来确定密钥长度。Kasiski 检验寻找可见规律,而重合指数法则衡量文本的底层统计结构。

重合指数是从一段文本中随机选取两个字母相同的概率。其公式为:

IC = Σ nᵢ(nᵢ - 1) / N(N - 1)

其中 nᵢ 是第 i 个字母(A 至 Z)的计数,N 是文本中的字母总数。

重合指数的期望值

不同类型的文本会产生特征性的重合指数值:

文本类型期望 IC
英语明文~0.0667
德语明文~0.0762
法语明文~0.0778
随机(均匀分布)~0.0385
维吉尼亚密文(短密钥)0.04 – 0.05
维吉尼亚密文(长密钥)~0.038

关键洞见在于:凯撒密码保留了原始语言的重合指数(因为它只是重新标记字母而不改变频率),而维吉尼亚加密会将重合指数降低至随机基准附近。

利用重合指数确定密钥长度

操作步骤系统如下:

  1. 对每个候选密钥长度 k(从 1 开始),从密文中每隔 k 个字母提取一个字母,构成 k 个独立子序列。
  2. 计算每个子序列的重合指数。
  3. 对所有 k 个子序列的重合指数取平均值。
  4. 当平均重合指数接近 0.0667(英语值)时,即找到了正确的密钥长度。

原理简洁明了:当你猜对密钥长度时,每个子序列由使用同一凯撒偏移加密的字母组成。这些字母保留了英语的频率分布(只是整体偏移),因此其重合指数与英语相符。当你猜错密钥长度时,子序列混合了使用不同偏移加密的字母,产生更平坦的分布和更低的重合指数。

例如,对一段密文测试各候选密钥长度可能得到:

候选密钥长度平均 IC
10.0421
20.0398
30.0412
40.0405
50.0638
60.0423
70.0401

密钥长度 5 处的明显峰值(IC = 0.0638,接近英语值 0.0667)揭示了正确的密钥长度。其他所有候选值的重合指数均接近随机基准 0.0385。

结合 Kasiski 检验与重合指数以提高置信度

实践中,经验丰富的密码分析者会同时使用两种方法。Kasiski 检验基于重复序列提供候选密钥长度,重合指数检验则确认哪个候选值是正确的。若 Kasiski 检验提示密钥长度为 4、6 或 12(作为观察到的距离的公因数),则对每个候选值计算重合指数将能识别出正确答案。这一组合方法正是我们的维吉尼亚密码解码器自动实现的方式。

第二阶段:还原每个密钥字母

一旦确定了密钥长度 k,最难的部分就完成了。密文被划分为 k 组,每组均使用单一凯撒偏移加密:

  • 第 1 组: 位置 1、k+1、2k+1、3k+1、… 处的字母
  • 第 2 组: 位置 2、k+2、2k+2、3k+2、… 处的字母
  • 第 k 组: 位置 k、2k、3k、4k、… 处的字母

每组都是一个简单的凯撒密码,而破解凯撒密码是基础操作。两种方法效果良好:

频率分析

对每组,统计每个字母的频率,并与预期的英语字母频率分布进行比较。该组中出现最频繁的字母很可能是 E(英语中最常见的字母)的加密结果。如果第 1 组中最常见的字母是 P,则该组的偏移量为 P - E = 11,即第一个密钥字母是 L(位置 11)。

这种方法在样本量较大(每组 100 个字母以上)时效果很好,但对于较小样本,统计波动可能导致分布失真,结果不够可靠。

卡方检验

更稳健的方法是对每个可能的偏移值(0 至 25)计算卡方统计量,选择产生最低卡方值的偏移——即与预期英语分布最接近的结果。

对某组应用偏移 s 后,卡方统计量为:

χ² = Σ (Oᵢ - Eᵢ)² / Eᵢ

其中 Oᵢ 是以偏移 s 解密后第 i 个字母的观测计数,Eᵢ 是基于英语字母频率的期望计数。

使 χ² 最小的偏移几乎肯定就是正确答案,即使样本量相对较小也同样有效。对每组遍历所有 26 个偏移并选择最小值,既快速又准确。

综合示例

假设 Kasiski 检验和重合指数分析确定密钥长度为 5。将密文分成 5 组,对每组进行卡方分析:

最佳偏移密钥字母
111L
24E
312M
414O
513N

还原的关键词为 LEMON。现在可以使用标准维吉尼亚解密公式对整条消息进行解密:

Pᵢ = (Cᵢ - Kᵢ + 26) mod 26

验证结果时,解密前几个词并检查是否构成连贯的英文。如果是,则密钥得到确认。

密钥长度与安全性

维吉尼亚密码的安全性几乎完全取决于关键词长度与明文长度之比。理解这一关系可以解释为何该密码在几个世纪内有效,以及为何最终走向失败:

密钥长度实际安全性弱点
1 个字母等同于凯撒密码暴力破解(25 个密钥)即可轻松攻破
3-5 个字母有 100 个以上密文字符即可轻松破解
6-12 个字母中等(对那个时代而言)可通过 Kasiski + 重合指数分析破解
20 个字母以上高(对那个时代而言)需要极长的密文才能攻击
= 明文长度(随机)理论上不可破译这就是一次性密码本(Vernam 密码)

一次性密码本——密钥真正随机、长度至少与消息相同且从不重复使用——是世界上唯一经过证明不可破译的加密方案。它是维吉尼亚原理的逻辑终点:使用足够长的密钥使其永不重复,从而消除 Kasiski 检验和重合指数所利用的周期性规律。

安全性评估:为何现代标准要求更高

维吉尼亚密码以现代标准衡量并不安全,其弱点不仅仅在于密钥过短:

弱点详情
密钥重复关键词循环使用,产生可被 Kasiski 分析利用的周期性规律
密钥长度是瓶颈安全性与密钥长度成正比;短密钥极易还原
易受重合指数分析统计方法仅凭密文即可确定密钥长度
无扩散性每个密文字母仅取决于一个明文字母和一个密钥字母
按位置确定性处于相同密钥字母位置的相同明文字母始终产生相同的密文

AES 等现代加密算法使用 128 至 256 位密钥,经过多轮变换,同时具备混淆和扩散特性,确保任何单个输入比特的改变都会影响每一个输出比特。维吉尼亚密码不具备其中任何一项特性。

历史上的密码破译:Babbage 与克里米亚战争

Charles Babbage(1791-1871),以设计第一台机械计算机而闻名的英国数学家,约于 1854 年秘密破解了维吉尼亚密码——比 Kasiski 发表的攻击方法早了近十年。Babbage 在自己的私人书房里发现,密文中的重复序列揭示了密钥长度,这与 Kasiski 后来独立发表的洞见本质上相同。

然而 Babbage 从未发表他的成果。历史学家认为这是刻意为之:英国情报机构很可能在克里米亚战争(1853-1856 年)期间利用这一技术破解了俄军及盟军的加密通信。公开这一方法会提醒对手注意到其中的漏洞。Babbage 的突破直到 20 世纪才通过他未发表的笔记被重新发现。

这一事件揭示了密码学史上反复出现的规律:政府秘密密码分析与公开学术知识之间的差距可能长达数十年。同样的动态在 1970 年代的美国国家安全局与公钥密码学领域再度上演。

现实中的失败:维吉尼亚密码在美国内战中的应用

美国内战(1861-1865 年)提供了一个生动的案例,说明维吉尼亚密码在实践中即便数学原理无懈可击也会如何失败。

南方邦联依靠维吉尼亚密码的一种变体进行战场通信。邦联军官使用黄铜密码盘——两个可旋转的同心字母轮,用于设置不同的偏移值——以及预先约定的周期性更换的关键词。据报道,邦联最常用的关键词是 "MANCHESTER BLUFF",也使用过 "COMPLETE VICTORY" 等密钥。

然而,邦联的实施存在严重缺陷:

  • 短且可预测的关键词。 通常是爱国口号,联邦密码分析者可以猜测或部分重建。
  • 密钥重复使用。 同一关键词在大量消息中反复使用,为 Kasiski 式分析提供了充足的密文。
  • 糟糕的操作安全性。 关键词有时以明文传输,或记录在被缴获的文件中。

联邦密码局由包括 Albert J. Myer 在内的密码分析者以及"神圣三人组"电报员(David Homer Bates、Albert Chandler 和 Charles Tinker)领导,定期破解邦联的维吉尼亚密码消息。邦联陆军的 Campbell Brown 上尉后来写道,该密码系统"管理如此之差,联邦当局大概在整个战争期间都定期解读了我们的电报。"

他们的成功印证了一条至今仍是现代密码学基础的原则:无论加密算法在数学上多么健全,如果密钥可预测、被重复使用或处理不当,消息就无法得到保护。 密钥管理与密码算法本身同等重要。

真实历史:Bellaso 与维吉尼亚的误会

被世人称为"维吉尼亚密码"的密码并非由 Blaise de Vigenère 发明。真正的发明者是意大利密码学家 Giovan Battista Bellaso,他于 1553 年在著作 La Cifra del Sig. Giovan Battista Bellaso 中发表了这种使用重复关键词的多表替换方法。

Bellaso 的创新颇为优雅:他没有使用固定偏移(如凯撒所做的),也没有使用渐进变化的偏移(如 Trithemius 于 1508 年提出的),而是引入了发送方和接收方事先约定的秘密关键词,关键词在消息中循环使用。

Blaise de Vigenère(1523-1596),法国外交官兼密码学家,于 1586 年在其著作 Traicté des Chiffres 中发表了一种不同且可以说更为复杂的密码。维吉尼亚真正发明的是一种自动密钥系统——密钥以一个引导字母开始,然后用明文本身生成后续密钥字母,使有效密钥不再重复。这是一种比以他名字命名的重复关键词密码根本上更强的系统。你可以在我们的自动密钥密码页面探索维吉尼亚的真正发明。

这一误归功于 19 世纪历史学家混淆了两种系统。待到错误被认识到时,"维吉尼亚密码"已成为 Bellaso 重复关键词方法的标准名称,这一用法延续至今。

用 Python 实现 Kasiski 分析

用实际的 Python 代码实现上述密码分析技术,有助于巩固这些概念。以下代码演示了 Kasiski 检验和基于重合指数的密钥长度检测:

from collections import Counter
import math

def find_repeated_sequences(ciphertext, min_length=3):
    """找出重复序列及其距离(Kasiski 检验)。"""
    sequences = {}
    text = ''.join(c for c in ciphertext.upper() if c.isalpha())

    for length in range(min_length, min(6, len(text) // 2)):
        for i in range(len(text) - length + 1):
            seq = text[i:i + length]
            if seq not in sequences:
                sequences[seq] = []
            sequences[seq].append(i)

    # 只保留出现超过一次的序列
    repeated = {seq: positions for seq, positions in sequences.items()
                if len(positions) > 1}

    # 计算距离
    distances = []
    for seq, positions in repeated.items():
        for i in range(len(positions) - 1):
            distances.append(positions[i + 1] - positions[i])

    return repeated, distances

def compute_ic(text):
    """计算文本的重合指数。"""
    counts = Counter(c for c in text.upper() if c.isalpha())
    n = sum(counts.values())
    if n <= 1:
        return 0
    return sum(c * (c - 1) for c in counts.values()) / (n * (n - 1))

def find_key_length_ic(ciphertext, max_key_length=20):
    """利用重合指数分析找出最可能的密钥长度。"""
    text = ''.join(c for c in ciphertext.upper() if c.isalpha())
    results = {}

    for key_len in range(1, min(max_key_length + 1, len(text) // 2)):
        groups = ['' for _ in range(key_len)]
        for i, char in enumerate(text):
            groups[i % key_len] += char

        avg_ic = sum(compute_ic(g) for g in groups) / key_len
        results[key_len] = avg_ic

    return results

def recover_key(ciphertext, key_length):
    """利用卡方分析还原密钥字母。"""
    text = ''.join(c for c in ciphertext.upper() if c.isalpha())
    english_freq = [0.0817, 0.0150, 0.0278, 0.0425, 0.1270,
                    0.0223, 0.0202, 0.0609, 0.0697, 0.0015,
                    0.0077, 0.0403, 0.0241, 0.0675, 0.0751,
                    0.0193, 0.0010, 0.0599, 0.0633, 0.0906,
                    0.0276, 0.0098, 0.0236, 0.0015, 0.0197, 0.0007]

    key = []
    for group_idx in range(key_length):
        group = text[group_idx::key_length]
        n = len(group)
        best_shift = 0
        best_chi2 = float('inf')

        for shift in range(26):
            chi2 = 0
            for i in range(26):
                observed = sum(1 for c in group
                              if (ord(c) - ord('A') - shift) % 26 == i)
                expected = english_freq[i] * n
                if expected > 0:
                    chi2 += (observed - expected) ** 2 / expected

            if chi2 < best_chi2:
                best_chi2 = chi2
                best_shift = shift

        key.append(chr(best_shift + ord('A')))

    return ''.join(key)

# 完整密码分析流程
ciphertext = "LXFOPVEFRNHR"  # 示例:用密钥 LEMON 加密 ATTACKATDAWN

# 第一步:利用重合指数确定密钥长度
ic_results = find_key_length_ic(ciphertext)
print("重合指数分析结果:")
for length, ic in sorted(ic_results.items()):
    marker = " <-- 可能正确" if ic > 0.06 else ""
    print(f"  密钥长度 {length}: IC = {ic:.4f}{marker}")

# 第二步:还原密钥
best_length = max(ic_results, key=lambda k: ic_results[k])
key = recover_key(ciphertext, best_length)
print(f"\n还原的密钥:{key}")

本实现严格遵循上文所述的两阶段方法:首先通过重合指数分析确定密钥长度,然后通过与预期英语字母频率的卡方检验还原每个密钥字母。如需完整的加密/解密实现,请访问维吉尼亚密码示例与代码页面。

相关密码与延伸阅读

维吉尼亚密码属于一个多表替换密码家族,了解其相关密码有助于加深对密码分析的认识:

  • 博福特密码 — 一种互反变体,密钥字母从固定位置相减而非相加。相同操作同时执行加密和解密,但同样易受 Kasiski 检验和重合指数分析攻击。
  • 自动密钥密码 — 维吉尼亚真正发明的密码。通过将明文本身作为密钥的一部分,消除了重复密钥的弱点,使 Kasiski 检验失效。但它有其自身基于已知明文攻击的漏洞。
  • 凯撒密码 — 单表替换前身。理解凯撒密码分析至关重要,因为维吉尼亚攻击的第二阶段本质上是独立求解多个凯撒密码。
  • 维吉尼亚方阵 — 用于手动维吉尼亚加密的 26×26 Tabula Recta。理解这张表有助于直观认识为何不同密钥字母产生不同的替换字母表。

从凯撒密码(单一偏移)到维吉尼亚密码(重复关键词),再到自动密钥(非重复密钥),直至一次性密码本(真正随机密钥)的演进,代表了密码学史上最重要的概念脉络之一。每一步都解决了前一种设计的特定弱点,而针对每种密码所发展出的攻击方法又推动了其继任者的发明。

亲自尝试

理解维吉尼亚密码分析的最好方式是动手实践。试用我们的免费维吉尼亚密码解码器,它内置自动 Kasiski 检验和密钥还原功能。粘贴任何经维吉尼亚加密的密文,工具将估算密钥长度、还原关键词并解密消息——所有这些都使用了本文所描述的技术。

关于本文

本文是我们综合 维吉尼亚密码 教程系列的一部分。继续了解古典密码学,并探索我们的交互式密码工具。

试用 维吉尼亚密码 工具

通过我们的交互式维吉尼亚密码工具,将所学知识付诸实践。

试用 维吉尼亚密码 工具