什么是维吉尼亚密码(Vigenère Cipher)?
维吉尼亚密码是一种多表替换密码,由 Giovan Battista Bellaso 于 1553 年发明。 它通过根据重复关键字对每个字母应用不同的凯撒位移来加密文本。若关键字为"KEY",则第一个字母位移 10(K = 10),第二个字母位移 4(E = 4),第三个字母位移 24(Y = 24),然后模式循环重复。这意味着同一个明文字母可以根据其位置加密为不同的密文字母——这正是多表替换密码区别于凯撒密码等单表替换密码的决定性特征。
在超过 300 年的时间里,从 1553 年发明到 1863 年首次公开密码分析,维吉尼亚密码被称为 "le chiffre indéchiffrable"——无法破解的密码。它通过平坦化字母频率分布,击败了那个时代所有已知的攻击方式,而正是字母频率分布使单表密码轻而易举地被破解。直到 Friedrich Kasiski 和独立研究的 Charles Babbage 开发出新的统计技术,这个密码才最终被攻破。
维吉尼亚密码的工作原理
加密公式
对于位置 i 处的每个明文字母,加密公式为:
Cᵢ = (Pᵢ + Kᵢ) mod 26
其中 Pᵢ 是明文字母的位置(A = 0,B = 1,… Z = 25),Kᵢ 是对应关键字字母的位置,mod 26 将结果限制在字母表范围内。
解密公式
Pᵢ = (Cᵢ − Kᵢ + 26) mod 26
维吉尼亚密码示例:用 LEMON 加密 "ATTACK AT DAWN"
用关键字 LEMON 加密 ATTACK AT DAWN:
| 位置 | 明文 | 关键字字母 | P + K | mod 26 | 密文 |
|---|---|---|---|---|---|
| 1 | A (0) | L (11) | 11 | 11 | L |
| 2 | T (19) | E (4) | 23 | 23 | X |
| 3 | T (19) | M (12) | 31 | 5 | F |
| 4 | A (0) | O (14) | 14 | 14 | O |
| 5 | C (2) | N (13) | 15 | 15 | P |
| 6 | K (10) | L (11) | 21 | 21 | V |
| 7 | A (0) | E (4) | 4 | 4 | E |
| 8 | T (19) | M (12) | 31 | 5 | F |
| 9 | D (3) | O (14) | 17 | 17 | R |
| 10 | A (0) | N (13) | 13 | 13 | N |
| 11 | W (22) | L (11) | 33 | 7 | H |
| 12 | N (13) | E (4) | 17 | 17 | R |
结果: ATTACK AT DAWN → LXFOPV EF RNHR
注意,位置 2 和 3 的两个 T 加密为不同的字母(X 和 F),因为它们与不同的关键字字母(E 和 M)对应。类似地,位置 1、4、7 的三个 A 分别变为 L、O 和 E。这种变化的替换正是频率分析对多表替换密码无效的原因所在。
Tabula Recta:维吉尼亚方阵
维吉尼亚方阵(又称 Vigenère 方阵或 Vigenère 表格)是一个 26×26 的字母网格,是手动执行维吉尼亚加密的传统查找工具。每行代表一种不同位移量的凯撒密码——第 A 行为位移 0,第 B 行为位移 1,依此类推。
使用维吉尼亚方阵加密字母的步骤:
- 找到与关键字字母对应的行。
- 找到与明文字母对应的列。
- 行列交叉处的字母即为密文字母。
本页预览表显示了完整网格的 6×6 部分。请在我们的互动维吉尼亚表格页面浏览完整的 26×26 维吉尼亚方阵,在那里您可以点击任意单元格查看加密关系。
维吉尼亚密码与凯撒密码对比
维吉尼亚密码常被描述为凯撒密码的多表升级版。下表列出了对密码分析最关键的几个维度:
| 属性 | 凯撒密码 | 维吉尼亚密码 |
|---|---|---|
| 类型 | 单表替换 | 多表替换 |
| 密钥 | 单个整数位移(0–25) | 任意长度的关键词 |
| 密钥空间 | 26 个可能密钥 | 26ⁿ(n 为关键词长度) |
| 是否易被简单频率分析攻破? | 是——字母频率直接保留 | 否——频率被各位置摊平 |
| 首次被通用方法破解 | 古典时期 | 1863 年(Kasiski 检测法) |
| 当代最佳攻击方式 | 对 26 种位移暴力穷举 | Kasiski + 重合指数 + 按列频率分析 |
如果维吉尼亚密码的关键词只有一个字母,它就退化成凯撒密码——凯撒本质上是 n = 1 的维吉尼亚密码。关键词长度一旦超过 1,密码便能抵抗朴素的频率分析,因为消息每个位置可能使用不同的位移字母表。
如何识别维吉尼亚密文
在尝试破解密码之前,判断是否面对维吉尼亚加密很有帮助。以下几个特征可将维吉尼亚密文与其他密码类型区分开来:
- 仅含字母,单词边界保留。 与凯撒密码一样,维吉尼亚密码传统上仅加密字母字符,保留空格和标点符号不变。单词长度与原始明文相同。
- 频率分布平坦但不均匀。 凯撒密码中,频率分布看起来像英语但发生了位移。而在维吉尼亚密文中,分布明显更加平坦——没有单个字母占主导地位——但也不是完全均匀的(完全均匀可能表明使用了一次性密码本或随机文本)。
- 重合指数介于 0.04 到 0.05 之间。 维吉尼亚密文的重合指数(IC)通常落在英语值(约 0.067)和随机值(约 0.038)之间,具体取决于密钥长度。处于这一中间范围的 IC 是多表替换的有力指示。
- 等间隔出现重复序列。 如果发现相同的 3 个及以上字母序列以共享公因数的间距出现,则文本很可能是维吉尼亚加密的(这是 Kasiski 分析法的基础)。
本站的密码识别器工具利用这些特征自动检测维吉尼亚加密并估计密钥长度。
使用 Python、Java 和 JavaScript 实现维吉尼亚密码
维吉尼亚密码是密码学课程的经典练习,因为核心数学只需要几行代码。以下代码片段会加密 A–Z 字母、保留大小写,并原样保留非字母字符。
Python
def vigenere_encrypt(text: str, key: str) -> str:
key = key.upper()
out, j = [], 0
for ch in text:
if ch.isalpha():
base = 65 if ch.isupper() else 97
shift = ord(key[j % len(key)]) - 65
out.append(chr((ord(ch) - base + shift) % 26 + base))
j += 1
else:
out.append(ch)
return "".join(out)
Java
static String vigenereEncrypt(String text, String key) {
key = key.toUpperCase();
StringBuilder out = new StringBuilder();
int j = 0;
for (char ch : text.toCharArray()) {
if (Character.isLetter(ch)) {
int base = Character.isUpperCase(ch) ? 'A' : 'a';
int shift = key.charAt(j % key.length()) - 'A';
out.append((char) ((ch - base + shift) % 26 + base));
j++;
} else {
out.append(ch);
}
}
return out.toString();
}
JavaScript
function vigenereEncrypt(text, key) {
key = key.toUpperCase();
let out = "", j = 0;
for (const ch of text) {
if (/[a-zA-Z]/.test(ch)) {
const base = ch >= "a" ? 97 : 65;
const shift = key.charCodeAt(j % key.length) - 65;
out += String.fromCharCode((ch.charCodeAt(0) - base + shift) % 26 + base);
j++;
} else {
out += ch;
}
}
return out;
}
解密时只需将位移从"加"改为"减":(ord(ch) - base - shift + 26) % 26 + base。
如何读 "Vigenère"
这个密码以 16 世纪法国外交官、密码学家 Blaise de Vigenère(1523–1596)命名。英文发音是 /ˌviːʒəˈnɛər/,读作 "vee-zhuh-NAIR",重音落在最后一个音节,中间的 g 发类似 "measure" 中的 zh 音。中文通常音译为"维吉尼亚"或"维热纳尔"。
正式拼写在第二个 e 上带法语抑音符(è)。日常书写和搜索中常常省略这个符号——"Vigenère cipher" 和 "Vigenere cipher" 指同一种密码——但带抑音符的写法才是正确形式。
维吉尼亚密码的现代应用场景
尽管已有数百年历史,维吉尼亚密码在现代语境中仍频繁出现:
- CTF 竞赛。 网络安全夺旗(CTF)挑战中,维吉尼亚加密常在中等难度关卡中出现。参赛者需要识别密码类型、确定密钥长度并恢复密钥以获取标志。
- 密室逃脱与谜题游戏。 维吉尼亚密码是多步骤谜题的热门选择,因为它同时需要密钥和密文,让谜题设计者可以将关键字藏在另一个单独线索中。
- 密码学课程。 维吉尼亚密码是大学密码学和信息安全课程中教授多表替换、密钥管理、Kasiski 分析和重合指数的标准示例。
- 流行文化。 维吉尼亚密码出现在电视剧《神秘小镇》(Gravity Falls)、视频游戏《命运 2》(Destiny 2)以及众多侦探小说中。动画《神秘小镇》曾在片尾字幕中使用维吉尼亚加密消息,关键字隐藏在每集剧情中。
- 历史重现。 内战爱好者和教育项目使用复制品同盟密码盘来演示符合时代特征的加密技术。
相关多表替换密码
维吉尼亚密码属于一个从同一核心思想演化而来的多表替换密码家族:
- 博福特密码 — 一种互逆变体,关键字字母从固定位置相减而非相加。博福特密码的加密和解密使用相同操作。
- 自动密钥密码 — Vigenère 本人的发明:密钥以一个引导字开头,然后将明文本身追加为密钥,消除了重复密钥的弱点。
- 格伦斯菲尔德密码 — 维吉尼亚密码的一个变体,将密钥限制为数字(0–9),将每个位置的密钥空间从 26 缩减到 10。
- 流水密钥密码 — 使用一段长文本(如书中某页)作为密钥,在不需要真正随机密钥的情况下接近一次性密码本的安全性。
- 特里塞缪斯密码 — 其前身,无秘密密钥地对每个字母依次位移(A=0,B=1,C=2,……)。Bellaso 的创新是将这种固定递进改为秘密关键字。
- 波尔塔密码 — 一种使用 13 个字母表的互逆双字母密码,设计为自逆系统。
- 泥淖密码 — 由四种变体组成的密码家族,将关键字混合字母表与维吉尼亚风格的多表位移相结合。
- 阿尔贝蒂密码 — 第一种多表替换密码,由 Leon Battista Alberti 于 1460 年代发明,使用旋转密码盘。Alberti 在加密过程中更换字母表的概念是所有后续多表替换系统(包括 Bellaso 的关键字方法)的先驱。
从 Alberti 密码盘(1460 年代)→ 特里塞缪斯的递进位移(1508 年)→ Bellaso 的关键字方法(1553 年)→ Vigenère 的自动密钥系统(1586 年)的演进,代表了密码学史上最重要的发展脉络之一,每一步都针对前一设计的弱点做出了改进。
延伸阅读
探索维吉尼亚密码的历史、密码分析技术和代码实现:
- 破解维吉尼亚密码:Kasiski 检验与重合指数 — 不依赖密钥破解维吉尼亚加密的逐步指南
- 凯撒密码与维吉尼亚密码:完整安全性比较 — 了解单表替换与多表替换的关键区别