经典加密法
01
仿射加密法
在说仿射加密之前,有必要先说一下单码加密。单码加密法具有固定替换模式的加密方法,即明文中的每个字母就由密文中的一个字母所替换。而仿射加密就是单码加密法的一种。
在仿射加密中,字母表的每个字母代表一个数字,例如a=0,b=1,c=2,……,z=25。仿射加密的秘钥为0~25之间的数字对(a,b),a与26的最大公约数必须为1,即GCD(a,26)=1,也就是说能整除a和26的只有1。例如,a=2就不行,因为2可以整除2和26。a=5就可以,因为只有1才能整除5和26。
假设p为明文子母的数字(即该字母在字母表中的数字),而c为密文字母的数字,那么,这两个数字有如下关系:
c = ap + b (mod 26)
p =a-1(c - b)(mod 26)
其中a-1(表示a的逆元,a,b∈Z26
例如,选取秘钥(7,3)。利用这个秘钥,将“hot”用仿射加密 法进行加密。先来看一下字母表:
所以,“hot”用数字表示就是7、14、19,分别用仿射加密生成密文:
c(h) = 77+3 mod 26 = 52 mod 26 = 0(a)
c(o) = 714+3 mod 26 = 101 mod 26 = 23(x)
c(t) = 719+3 mod 26 = 136 mod 26 = 6(g)
因此,“hot”经过仿射加密通过秘钥(7,3)加密之后的密文为“axg”
加密(python):
#-*-coding:utf-8-*-
print "请输入秘钥中的a:"
a = input()
print "请输入秘钥中的b:"
b = input()
print "请输入的明文:"
pla = raw_input()
cip = []
for i in pla:
#计算出明文字母对应的数字
p = ord(i) - 97
#利用公式计算密文数字,并转换成对应的字母
c = a * p + b % 26
while c > 25:
c = c % 26
c = chr(c + 97)
cip.append(c)
print "得到的密文是:"
print ''.join(cip)
运行示例:
当然也可以用CAP软件
选择Ciphers中的Affine
解密:
分析:由于GCD(a,26)=1,a,b∈Z26,所以a有12种结果,分别为:1、3、5、7、9、11、15、17、19、21、23、25,然后利用公式解密。每一个d对应12种结果,如果输入的d正确,那么明文肯定就在这12种结果当中。
这里我直接使用这些数字的逆元。
数据如下:
#-*-coding:utf-8-*-
print "请输入密文:"
cip = raw_input()
print "请输入秘钥中的b:"
b = input()
pla = []
#0~25中符合GCD(a,26)=1的数字及其它的逆元
ny_dic = {1:1,3:9,5:21,7:15,9:3,11:19,15:7,17:23,19:11,21:5,23:17,25:25}
#字典中的键值
dic = [1,3,5,7,9,11,15,17,19,21,23,25]
print "可能的明文为:"
for j in dic:
for i in cip:
c = ord(i) - 97
p = ny_dic[j] * (c - b) % 26
while p > 25:
p = p % 26
p = chr(p + 97)
pla.append(p)
print ''.join(pla)
pla = []
运行示例:
可以看到明文就在其中。
也可以使用CAP,选择Simple Analysis中的Affine
输入可能的替换进行分析。
多文字加密法
02
多文字加密法也是单码加密法的一种,它用一对字母来代替一个明文字母,所以加密后的密文长度是明文长度的两倍。多文字加密法使用一个55的矩阵,这个矩阵的5行和5列使用含有5个字母的关键词来加密,这个关键词不能有重复的字母,26个英文字母置于这个矩阵中,因为矩阵只有25个位置,所以字母“i”和“j”占用同一个单元,意味着所有的“j”都变成了“i”。例如关键词为codes,那么秘钥的矩阵为:
每个明文字母由标识该字母的行和列的字母对替代。例如,在这个表中明文“a”的密文就是“cc”,明文“hello”加密后的密文就是“odcsdcdcde”,解密过程就是反向查找矩阵。
加密(python):
#-*-coding:utf-8-*-
print "请输入需要加密的字符串:"
pla = raw_input()
print "请输入秘钥:"
key = raw_input()
cip = []
#定义好矩阵
table= [['',key[0],key[1],key[2],key[3],key[4]],[key[0],'a','b','c','d','e'],[key[1],'f','g','h','i','k'],[key[2],'l','m','n','o','p'],[key[3],'q','r','s','t','u'],[key[4],'v','w','x','y','z']]
for k in pla:
#当明文中有“j”的时候,当做“i”进行处理
if k == 'j':
k = 'i'
for i in range(1,6):
for j in range(1,6):
if k == table[i][j] and k != 'j':
cip.append(table[i][0])
cip.append(table[0][j])
print "加密后的密文为:"
print ''.join(cip)
运行示例:
使用CAP进行加密
选择Ciphertext中的MultiLiteral
结果相同
解密:
分析:由于加密秘钥由5个字母组成,所以很容易被破解,只要将密文加以分析,重新进行排列组合即可。提取出不同的字母,进行排列组合,组合成新的秘钥,根据密文进行反向查找矩阵即可。
解密程序(python):
#-*-coding:utf-8-*-
import collections
print "请输入需要解密的密文:"
cip = raw_input()
#将密文拆分,两个两个一组存放
cip_res = []
for i in range(0,len(cip),2):
cip_res.append(cip[i:i+2])
#存放密文的所有组合
key_res = []
pla = []
#去除重复字母
key = ''.join(collections.OrderedDict.fromkeys(cip))
for i1 in key:
for i2 in key:
for i3 in key:
for i4 in key:
for i5 in key:
if i1 not in (i2 + i3 + i4 + i5) and i2 not in (i1 + i3 + i4 + i5) and i3 not in (i1 + i2 + i4 + i5) and i4 not in (i1 + i2 + i3 + i5) and i5 not in (i1 + i2 + i3 + i4):
key_res.append(i1+i2+i3+i4+i5)
for z in range(len(key_res)):
key = key_res[z]
table = [['',key[0],key[1],key[2],key[3],key[4]],[key[0],'a','b','c','d','e'],[key[1],'f','g','h','i','k'],[key[2],'l','m','n','o','p'],[key[3],'q','r','s','t','u'],[key[4],'v','w','x','y','z']]
for i in cip_res:
for j in range(len(table[0])):
#记录第一个下标
if i[0] == table[0][j]:
a = j
#记录第二个下标
if i[1] == table[0][j]:
b = j
s = table[a][b]
pla.append(s)
j = 0
with open('res.txt','w') as f:
for i in range(0,len(pla),len(cip_res)):
f.write("秘钥:" + key_res[j] + " ")
f.write("明文:" + ''.join(pla[i:i+len(cip_res)]))
f.write('\n')
j = j + 1
运行示例:
结果会保存在一个名为res.txt文件中,文件截图(部分)如下:
可以看到加密所使用的秘钥和对应的明文。
通过分析明文特点(属于英文单词),可以更快确定明文。毕竟明文不大可能是一堆没有意义的字符串。
使用CAP解密: 选择Analysis tools中的Multil
与我所写的Python解密程序结果相同。
03
Vigenere(维吉尼亚)加密法
Vigenere加密法属于多码加密法。而多码加密法是一种替换加密法,其替换形式是:其中的每个明文字母可以用密文中的多个字母来代替,而每个密文字母也可以表示多个明文字母。例如,明文字母“e”可能在密文中有时出现为“f”,有时又出现为“m”;而密文子母“s”有时可以表示明文“g”,有时又可以表示明文“c”。这种加密法可以干扰字母出现频率分析法。
Vigenere加密法是基于关键词的加密系统,但不像单码关键词加密法那样使用关键词来定义替换模式的,关键词在上边不断重复书写,这样每个明文子母都与一个关键词的字母关联。例如,如果关键词为“hold”,而明文为“this is the plaintext”,那么关键词和明文的对应如下表所示:
加密的过程就是使用秘钥字母作为行,使用明文字母对应列,查找Vigenere表然后确定密文字母。Vigenere表如下:
通过对照Vigenere表,可以得出使用关键词“hold”加密明文“this is the plaintext”得到的密文为“avtv pg ekl dwdpbehdh”
加密: 使用CAP软件加密:
在加密法里选择Vigenere
解密: 分析:在解密过程中,我们不知道秘钥是什么,也不知道秘钥的长度。我们可以根据kasiski测试法来测试。
kasiski测试法:于19世纪由波兰的一个军官发现的,这种方法通过查看重复密文部分,来发现多码密钥的长度。
当字符数目足够多的时候,如果字符串在明文中重复,而相同的明文字符串使用关键词中相同的部分进行加密,这样得到的密文中就有相同的部分。然后统计这些相同的结果,算出他们之间的间距,然后取其最大公约数,就可以确定其秘钥的长度。
例如使用秘钥“run”加密明文“to be or not to be that is the quest”得到的密文为“kiovieeigkiovnurnvjnuvkhvmg”
可以看出最大公约数为3,那么秘钥的长度就可能为3。因本人能力有限,未能写出具体的程序进行解密。具体的解密过程及其代码,可以参考
http://blog.csdn.net/u013046245/article/details/20612637,过程很详细。
参考《经典密码学与现代密码学》