Python环境下,未知双密钥时如何解密采用affine(vigenere(text, vigenere_key), *affine_key)流程加密的文本?
嘿,我完全懂你现在的挫败感——双重加密+双未知密钥,直接暴力破解确实是死胡同。不过咱们换个角度,仿射密码的密钥空间其实极小,这就是咱们的突破口,一步步来:
破解核心思路:先枚举仿射密钥,再破解维吉尼亚
维吉尼亚的密钥理论上可以无限长,但仿射密钥的可能组合只有312种(12种合法的a值 × 26种b值),完全可以暴力枚举。只要逆仿射后得到真实的维吉尼亚加密文本,再用标准方法破解维吉尼亚就轻松多了。
步骤1:搞清楚仿射逆变换的规则
假设加密的是26个英文字母(先统一成大写或小写处理),仿射加密的逆变换公式是这样的:
把密文字符转成0-25的数字(比如A=0,Z=25),逆变换后得到维吉尼亚加密的中间文本字符:
m_num = (a_inv * (c_num - b)) % 26
其中:
a必须是和26互质的整数,可选值只有12个:[1,3,5,7,9,11,15,17,19,21,23,25]b是0-25的任意整数a_inv是a在模26下的乘法逆元(比如3的逆元是9,因为3×9=27≡1 mod26)
我给你预计算好了所有a对应的逆元,直接用就行:
a: 1 → 逆元1;a:3→9;a:5→21;a:7→15;a:9→3;a:11→19 a:15→7;a:17→23;a:19→11;a:21→5;a:23→17;a:25→25
步骤2:枚举所有仿射逆变换组合
写个简单的Python脚本,遍历每一组(a,b),对整个密文做逆仿射变换,得到候选的“维吉尼亚加密文本”。伪代码大概是这样:
# 预定义a的逆元映射 a_inverses = { 1:1, 3:9, 5:21, 7:15, 9:3, 11:19, 15:7, 17:23, 19:11, 21:5, 23:17, 25:25 } ciphertext = "这里替换成你的密文" ciphertext_upper = ciphertext.upper() # 遍历所有仿射密钥组合 for a, a_inv in a_inverses.items(): for b in range(26): vigenere_candidate = [] for char in ciphertext_upper: # 跳过非字母字符(如果有的话) if not char.isalpha(): vigenere_candidate.append(char) continue c_num = ord(char) - ord('A') # 执行逆仿射计算 m_num = (a_inv * (c_num - b)) % 26 vigenere_candidate.append(chr(m_num + ord('A'))) # 得到当前组合对应的维吉尼亚候选文本 candidate_str = ''.join(vigenere_candidate) # 接下来对这个候选文本做维吉尼亚破解
步骤3:破解每个候选的维吉尼亚文本
对于每个逆仿射得到的候选文本,用维吉尼亚的标准破解流程:
- 卡西斯基测试:找出文本中重复的短字符串,计算它们之间的距离,取这些距离的最大公约数(GCD),这个数大概率就是维吉尼亚密钥的长度。
- 按密钥长度分组:把文本拆成
密钥长度个小组,每个小组对应维吉尼亚密钥中某一个字符的单字母移位加密。 - 频率分析:对每个小组统计字符频率,和英文常用字符频率(比如E是出现最多的,占比~12%)对比,找出对应的移位量(也就是密钥字符)。
- 验证明文:用得到的密钥解密,看结果是否是有意义的可读文本。
你可以自己实现这些步骤,或者用pycipher这类密码学库来简化维吉尼亚的破解——比如用pycipher.Vigenere的破解方法直接处理候选文本。
为什么这个方法可行?
仿射的312种组合完全在计算机的处理范围内,只要枚举到正确的(a,b),逆仿射后的文本就是真实的维吉尼亚加密结果,这时候用频率分析破解维吉尼亚的成功率极高,根本不需要暴力所有可能的密钥。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

