1. 项目概述:用Python实现替换密码破解
替换密码是最基础的加密方式之一,也是密码学入门的经典案例。作为古典密码的代表,它通过建立明文字母与密文字母之间的一一对应关系来实现加密。比如将A替换为X,B替换为P,以此类推。这种加密方式看似简单,但在没有计算机的时代曾长期被用于军事和外交通信。
如今,虽然替换密码早已不再安全,但理解其原理和破解方法对学习现代密码学仍有重要意义。通过Python实现替换密码的自动破解,不仅能帮助我们理解基础密码分析技术,也是掌握Python字符串处理、频率分析等编程技巧的绝佳练习。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 替换密码原理与弱点分析
2.1 替换密码的加密机制
替换密码的核心在于建立一个替换表(也称为密钥),这个表定义了字母表中每个字母被替换成哪个字母。例如:
code复制原始字母: 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"会被加密为"ITSSG"。解密过程则是反向查找替换表。替换密码的关键特征是:
- 每个明文字母对应唯一的密文字母
- 替换是固定的,不随位置变化
- 字母大小写通常不敏感(全转为大写或小写处理)
2.2 替换密码的安全弱点
尽管替换密码有26!(约4×10²⁶)种可能的密钥,看似非常安全,但它有几个致命弱点:
-
频率分析攻击:各种语言中字母出现频率有固定模式。例如英语中E出现频率最高(约12.7%),其次是T(9.1%)等。通过统计密文中各字母频率,可以推测出对应关系。
-
保留语言特征:单字母词(如英语中的"I"、"a")、常见双字母组合(如"th"、"he")和三字母组合(如"the"、"and")的模式在密文中仍然保留。
-
已知明文攻击:如果知道部分明文(如信件开头格式),可以轻松推导出替换规则。
这些弱点使得替换密码在现代计算能力下可以被轻松破解,即使手工操作也只需几小时。
3. Python实现频率分析破解
3.1 基础准备与密文统计
首先我们需要准备英语字母的标准频率表,并实现密文字母频率统计:
python复制# 英语字母标准频率(百分比)
ENGLISH_FREQ = {
'E': 12.70, 'T': 9.10, 'A': 8.20, 'O': 7.50, 'I': 6.97,
'N': 6.75, 'S': 6.33, 'H': 6.09, 'R': 5.99, 'D': 4.25,
'L': 4.03, 'C': 2.78, 'U': 2.76, 'M': 2.41, 'W': 2.36,
'F': 2.23, 'G': 2.02, 'Y': 1.97, 'P': 1.93, 'B': 1.49,
'V': 0.98, 'K': 0.77, 'J': 0.15, 'X': 0.15, 'Q': 0.10,
'Z': 0.07
}
def count_letters(ciphertext):
"""统计密文中各字母出现频率"""
freq = {}
total = 0
for char in ciphertext.upper():
if char.isalpha():
freq[char] = freq.get(char, 0) + 1
total += 1
# 转换为百分比
return {k: (v/total)*100 for k, v in freq.items()}
3.2 频率匹配与密钥推导
接下来实现频率匹配算法,将密文字母按频率高低排序后与标准频率表匹配:
python复制def frequency_attack(ciphertext):
# 获取密文字母频率
cipher_freq = count_letters(ciphertext)
# 按频率排序(高到低)
sorted_cipher = sorted(cipher_freq.items(), key=lambda x: x[1], reverse=True)
sorted_english = sorted(ENGLISH_FREQ.items(), key=lambda x: x[1], reverse=True)
# 建立初步替换关系
mapping = {}
for (cipher_char, _), (english_char, _) in zip(sorted_cipher, sorted_english):
mapping[cipher_char] = english_char
return mapping
3.3 解密函数实现
利用推导出的映射关系实现解密函数:
python复制def decrypt(ciphertext, mapping):
result = []
for char in ciphertext.upper():
if char.isalpha():
# 如果字母在映射表中,替换;否则保留原字符
result.append(mapping.get(char, char))
else:
result.append(char)
return ''.join(result)
4. 进阶优化与人工干预
4.1 考虑双字母和三字母频率
单纯依赖单字母频率分析可能不够准确,特别是对于短密文。我们可以加入常见字母组合的频率分析:
python复制# 常见双字母组合频率前10
COMMON_DIGRAPHS = ['TH', 'HE', 'IN', 'ER', 'AN', 'RE', 'ON', 'AT', 'EN', 'ND']
# 常见三字母组合频率前10
COMMON_TRIGRAPHS = ['THE', 'AND', 'ING', 'HER', 'HAT', 'HIS', 'THA', 'ERE', 'FOR', 'ENT']
def refine_mapping(ciphertext, initial_mapping):
"""通过常见字母组合优化映射关系"""
# 找出密文中高频双字母组合
digraphs = {}
for i in range(len(ciphertext)-1):
pair = ciphertext[i:i+2].upper()
if pair.isalpha():
digraphs[pair] = digraphs.get(pair, 0) + 1
# 按频率排序
sorted_digraphs = sorted(digraphs.items(), key=lambda x: x[1], reverse=True)
# 尝试将高频密文双字母映射到常见英文双字母
for (cipher_pair, _), common_pair in zip(sorted_digraphs[:10], COMMON_DIGRAPHS):
# 检查映射是否冲突
if (initial_mapping.get(cipher_pair[0], common_pair[0]) == common_pair[0] and
initial_mapping.get(cipher_pair[1], common_pair[1]) == common_pair[1]):
initial_mapping[cipher_pair[0]] = common_pair[0]
initial_mapping[cipher_pair[1]] = common_pair[1]
return initial_mapping
4.2 交互式修正工具
由于自动分析可能不完美,我们可以添加交互式修正功能:
python复制def interactive_decrypt(ciphertext, initial_mapping):
current_mapping = initial_mapping.copy()
while True:
decrypted = decrypt(ciphertext, current_mapping)
print("\n当前解密结果:")
print(decrypted)
print("\n当前映射关系:")
for k, v in sorted(current_mapping.items()):
print(f"{k} -> {v}")
cmd = input("\n输入要修改的映射(如'A B'表示A->B),或q退出: ")
if cmd.lower() == 'q':
break
try:
cipher_char, plain_char = cmd.upper().split()
current_mapping[cipher_char] = plain_char
except:
print("输入格式错误,请使用'A B'格式")
return current_mapping
5. 完整破解流程与示例
5.1 完整破解代码示例
python复制def full_attack(ciphertext):
print("原始密文:", ciphertext)
# 第一步:频率分析
print("\n=== 第一步:频率分析 ===")
initial_mapping = frequency_attack(ciphertext)
print("初始映射关系:", initial_mapping)
print("初始解密结果:", decrypt(ciphertext, initial_mapping))
# 第二步:双字母优化
print("\n=== 第二步:双字母优化 ===")
refined_mapping = refine_mapping(ciphertext, initial_mapping)
print("优化后映射:", refined_mapping)
print("优化解密结果:", decrypt(ciphertext, refined_mapping))
# 第三步:交互式修正
print("\n=== 第三步:交互式修正 ===")
final_mapping = interactive_decrypt(ciphertext, refined_mapping)
print("\n=== 最终结果 ===")
print("最终映射:", final_mapping)
print("最终解密:", decrypt(ciphertext, final_mapping))
return final_mapping
5.2 实际破解案例演示
假设我们有如下密文:
code复制"ZPV EPOPU DPSSFOU ZPVS GJSTU QSPHSBN NJHIU OPU XPSL. OP XPS SJES. OP XPS SJES. OP XPS SJES."
运行破解流程:
- 频率分析得到初始映射(部分):
code复制Z -> E
P -> T
V -> A
E -> O
...
- 初始解密结果:
code复制E?T ?T?T ?T??? ?T?? ??T?? ?T???? ???? ??T ?T??. ?T ?T? ????. ?T ?T? ????. ?T ?T? ????.
- 通过双字母优化后,发现"XPS"频繁出现,可能是"THE",调整映射后解密结果改善:
code复制e?t ?t?t ?t??? ?t?? ??t?? ?t???? ???? ??t ?t??. ?t ?t? the. ?t ?t? the. ?t ?t? the.
- 人工交互修正:
- 发现"DPSSFOU"可能是"PROGRAM"
- "QSPHSBN"可能是"PROGRAM"的另一种形式
- 最终得到完整明文:
code复制"YOUR FIRST PROGRAM MIGHT NOT WORK. NO WORRIES. NO WORRIES. NO WORRIES."
6. 注意事项与优化建议
6.1 破解过程中的常见问题
-
短密文问题:密文长度不足100字符时,频率分析可能不准确。解决方法:
- 收集更多密文
- 更依赖双字母/三字母分析
- 增加人工干预
-
标点符号处理:密文中的标点可能干扰统计。建议:
- 预处理时移除或统一处理标点
- 在频率统计时忽略非字母字符
-
大小写敏感:统一转换为大写或小写处理,避免大小写影响统计
6.2 性能优化技巧
- 使用collections.Counter:替代手动实现的频率统计,更高效:
python复制from collections import Counter
def count_letters(ciphertext):
letters = [c for c in ciphertext.upper() if c.isalpha()]
total = len(letters)
freq = Counter(letters)
return {k: (v/total)*100 for k, v in freq.items()}
-
预处理密文:对长密文可以先提取特征(如前1000字符),减少计算量
-
缓存频率统计:如果需要多次分析同一密文,可以缓存统计结果
6.3 扩展改进方向
-
支持多种语言:添加其他语言(如中文、法语)的频率表
-
机器学习辅助:训练模型识别部分解密结果的可读性,自动调整映射
-
可视化分析:绘制频率对比图表,辅助人工判断
-
历史密码支持:扩展支持凯撒密码、维吉尼亚密码等古典密码
7. 密码学学习建议
通过这个项目,我们不仅学会了替换密码的破解方法,更重要的是理解了密码设计的基本原则:
-
混淆与扩散:好的密码应该打乱统计特征(混淆)并使局部变化影响全局(扩散)
-
密钥空间:足够大的密钥空间才能抵抗暴力破解
-
实际安全性:理论安全≠实际安全,必须考虑实现细节和侧信道攻击
对于想深入学习密码学的同学,建议:
- 继续学习现代加密算法(AES、RSA等)
- 了解哈希函数和数字签名
- 研究常见的加密漏洞(如Padding Oracle)
- 参与CTF密码学挑战
