什么是置换加密呢?
前面说到凯撒密码是基于字母表进行平移映射,形成新的字母表,这种方法是容易被暴力破解的。那么置换加密和凯撒密码有什么不同和相同之处呢?
- 基于置换
- 密钥为26个字母的全排列之一(不可能进行暴力破解)
- 加密过程:对于每个单字母查表,改为对应字母
- 解密过程:反向查表
- 破解方式:?
- 凯撒密码可以看作单表置换的一类特殊情况
示例如下:
利用密钥对明文进行替换:a->d, b->q …
置换加密为什么不能被暴力破解?
我们来看一下,如若想要用暴力破解置换加密:
首先,我们来看一下26的阶乘:
import math
import time
n = math.factorial(26)
print(n)
如果只是单纯进行循环,我们走完26的阶乘需要几年呢?
t1 = time.time()
for _ in range(1000000):
pass
t2 = time.time()
time = t2 - t1
years = time*(n/1000000)/60/60/24/365
print(years)
答案是这么多年:
基于以上的分析我们可以知道,基本上不可能对置换加密进行暴力破解。
置换加密的python实现
import string
import random
def generate_key():
letters = [l for l in string.ascii_letters[26:]]
random.shuffle(letters) #打乱字母顺序
return dict(zip(string.ascii_letters[26:],letters))
def encrypt(key, message):
cipher = ""
for l in message:
if l in key:
cipher += key[l]
else:
cipher += l
return cipher
key = generate_key()
print(key)
print(encrypt(key, "ATTACK"))
实现结果:
置换加密如何破解?
词频分析
通过计算英文字符在密码其中出现的频率,与明文中英文字符出现的频率进行对比,对应,最终破解。
假设明文的根据词频排序如下表:
letter_freq = {
"e": 0.127,
"t": 0.096,
"a": 0.0817,
"o": 0.0751,
"i": 0.0697,
"n": 0.0675,
"s": 0.0633,
"h": 0.0609,
"r": 0.0599,
"d": 0.0425,
"l": 0.0403,
"c": 0.0278,
"u": 0.0276,
"m": 0.0241,
"w": 0.0236,
"f": 0.0223,
"g": 0.0202,
"y": 0.0197,
"p": 0.0193,
"b": 0.015,
"v": 0.0098,
"k": 0.0077,
"j": 0.0015,
"q": 0.001,
"z": 0.0007,
}
我们随后再计算密码中的词频:
def cipher_frequency():
cipher_freq = {k: 0 for k in string.ascii_letters[:26]}
counter = 0
for k in cipher:
if k in cipher_freq:
cipher_freq[k] += 1
counter += 1
for k in cipher_freq:
cipher_freq[k] = round(cipher_freq[k] / counter, 4) #统计某个字母出现的频率
cipher_freq = dict(
sorted(cipher_freq.items(), key=lambda item: item[1], reverse=True) #对词频进行排序
)
print(cipher_freq)
return cipher_freq
decrypt_key = dict(zip(cipher_freq.keys(), letter_freq.keys()))
print(decrypt_key)
最后得到密码中的词频结果为:
{
'r': 0.13,
'b': 0.1053,
'm': 0.096,
'k': 0.0759,
'j': 0.0743,
'w': 0.0728,
'i': 0.0635,
'p': 0.0464,
'u': 0.0372,
'd': 0.0356,
'h': 0.0356,
'v': 0.0341,
'x': 0.031,
'y': 0.0294,
'n': 0.0263,
's': 0.0263,
't': 0.0201,
'l': 0.0124,
'o': 0.0108,
'q': 0.0108,
'a': 0.0077,
'c': 0.0077,
'e': 0.0077,
'f': 0.0015,
'g': 0.0015,
'z': 0.0
}
所以我们可以认为,明文词频和密码词频的排序具有对应关系,也就是说e->r,t->b...,z->z
我们新建的解密索引表如下:
{'r': 'e',
'b': 't',
'm': 'a',
'k': 'o',
'j': 'i',
'w': 'n',
'i': 's',
'p': 'h',
'u': 'r',
'd': 'd',
'h': 'l',
'v': 'c',
'x': 'u',
'y': 'm',
'n': 'w',
's': 'f',
't': 'g',
'l': 'y',
'o': 'p',
'q': 'b',
'a': 'v',
'c': 'k',
'e': 'j',
'f': 'q',
'g': 'z'}
随后进行解密:
def decrypt(decrypt_key):
decrypt_str = ''
for s in cipher:
if s in decrypt_key:
decrypt_str += decrypt_key[s]
else:
decrypt_str += s
return decrypt_str
decrypt_code = decrypt(decrypt_key)
print(decrypt_code)
最后获取解密后的结果:
这个解密过程,可以进行人工的干预调整,将新建的索引表进行调整,最后可以获得结果:
因此,我们也可以知道,置换加密也是一种十分不安全的算法。