一、密码分析的概念和方法
-
唯密文攻击 (Ciphertext-only Attack):攻击者只有密文,没有任何明文或密钥信息。从密文中恢复出明文或密钥,是最困难的分析条件。
-
已知明文攻击 (Known-plaintext Attack):攻击者拥有部分密文和对应的明文,利用已知的明文-密文对来推导出密钥或破解其他密文。
-
选择明文攻击 (Chosen-plaintext Attack):攻击者可以选择任意明文并获取其对应的密文。
-
选择密文攻击 (Chosen-ciphertext Attack):攻击者可以选择任意密文并获取其对应的明文。
英文字母频率分析
-
26个字母在英文语言中出现的频率排序(E出现的频率远高于其他字母)
-
许多双字母的固定序列经常出现
二、仿射密码的密码分析
- 本质:求解二元一次方程
三、代换密码的密码分析
- 比较复杂,需要先猜出e,然后根据二字字母组合分别推测出其他单词
四、希尔密码的密码分析
- 分析目标:获得矩阵 K i , j K_{i,j} Ki,j
- 希尔密码较难采用唯密文攻击进行分析。比较适用于已知明文攻击,即如果能获得一些明密文对,则较容易破解出密钥K。 Y = X K → K = X − 1 Y Y=XK \rightarrow K=X^{-1}Y Y=XK→K=X−1Y
- 如果不知道m,可采用尝试法。
五、维吉尼亚密码的密码分析
分析要点
- 如果知道密钥字长度m,可以分解为m个单表代换密码分析任务。
- 确认密钥字长度m是关键。
- Kasiski法(1863,Friedrich Kasiski )
- 重合指数法(1920,William Friedman)
1. Kasiski法
2. 重合指数法
举例
已知密文:
CHREEVOAHMAERATBIAXXWTNXBEEOPHBSBOMOEOERBWRVXUOAKXAOSXXWEAHBWGJMMOMNKGRFVGXWTRZXWIAKLXFPSKAUTEMNDCMGTSXMXBTUIADNGMGPSRELXNJELXVRVPRTULHDNOWTWDTYGBPHXTFALJHASVBFXNGLLCHRZBWELEKMSJIKNBHWRJGNMGJSGLXFEYPHAGNRBIEOJTAMRVLCRREMNDGLXRRIMGNSNRWCHROHAEYEVTAOEBBIPEEWEVKAKOEWADREMXMTBHHCHRTKDNVRZCHRCLOOHPWOAIIWXNRMGWOIIFKEE
代码
def calculate_ic(ciphertext):
# 统计每个字母的出现次数
def calculate_block_ic(block):
letter_count = {}
total_letters = 0
for char in block:
if char.isalpha(): # 只考虑字母字符
char = char.upper()
if char in letter_count:
letter_count[char] += 1
else:
letter_count[char] = 1
total_letters += 1
# 计算重合指数
if total_letters <= 1:
return 0
ic = 0
for count in letter_count.values():
ic += count * (count - 1)
ic /= total_letters * (total_letters - 1)
return ic
# 计算每个块的重合指数
ic_values = []
for keyword_length in range(1, 8): # 关键词长度从1到7
block_ic_values = []
for i in range(keyword_length):
block = ciphertext[i::keyword_length]
ic = calculate_block_ic(block)
block_ic_values.append(ic)
ic_values.append(block_ic_values)
return ic_values
# 密文
ciphertext = "CHREEVOAHMAERATBIAXXWTNXBEEOPHBSBOMOEOERBWRVXUOAKXAOSXXWEAHBWGJMMOMNKGRFVGXWTRZXWIAKLXFPSKAUTEMNDCMGTSXMXBTUIADNGMGPSRELXNJELXVRVPRTULHDNOWTWDTYGBPHXTFALJHASVBFXNGLLCHRZBWELEKMSJIKNBHWRJGNMGJSGLXFEYPHAGNRBIEOJTAMRVLCRREMNDGLXRRIMGNSNRWCHROHAEYEVTAOEBBIPEEWEVKAKOEWADREMXMTBHHCHRTKDNVRZCHRCLOOHPWOAIIWXNRMGWOIIFKEE"
# 计算并输出每个关键词长度的每个分块的重合指数
ic_values = calculate_ic(ciphertext)
for keyword_length, block_ic_values in enumerate(ic_values, start=1):
print(f"关键词长度 {keyword_length}:")
for i, ic in enumerate(block_ic_values):
print(f" 块 {i + 1} 的重合指数: {ic:.4f}")
print() # 打印空行分隔不同关键词长度的结果
结果
关键词长度 1:
块 1 的重合指数: 0.0464
关键词长度 2:
块 1 的重合指数: 0.0461
块 2 的重合指数: 0.0437
关键词长度 3:
块 1 的重合指数: 0.0454
块 2 的重合指数: 0.0504
块 3 的重合指数: 0.0471
关键词长度 4:
块 1 的重合指数: 0.0422
块 2 的重合指数: 0.0403
块 3 的重合指数: 0.0473
块 4 的重合指数: 0.0443
关键词长度 5:
块 1 的重合指数: 0.0630
块 2 的重合指数: 0.0681
块 3 的重合指数: 0.0707
块 4 的重合指数: 0.0608
块 5 的重合指数: 0.0724
关键词长度 6:
块 1 的重合指数: 0.0443
块 2 的重合指数: 0.0437
块 3 的重合指数: 0.0475
块 4 的重合指数: 0.0475
块 5 的重合指数: 0.0498
块 6 的重合指数: 0.0370
关键词长度 7:
块 1 的重合指数: 0.0465
块 2 的重合指数: 0.0455
块 3 的重合指数: 0.0404
块 4 的重合指数: 0.0535
块 5 的重合指数: 0.0485
块 6 的重合指数: 0.0370
块 7 的重合指数: 0.0370
含明显,当关键词长度 = 5时,重合指数接近0.065。