首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >经典加密法

经典加密法

作者头像
安恒网络空间安全讲武堂
发布2018-02-06 15:42:52
1.4K0
发布2018-02-06 15:42:52
举报

经典加密法

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,过程很详细。

参考《经典密码学与现代密码学》

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-01-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 恒星EDU 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档