实验二:Many Time Pad
一、问题描述:
如下所示是 11 个使用同一个密钥按照 one time pad 方法进行加密得到的密文。 请使用前 10 个密文进行分析,并对目标密文进行解密。其中消息是[a-zA-Z]以及空格组成的字符,使用 ascii 编码,密文使用 hex 编码。
密文略。
本次实验将尝试探索当密钥被重复使用时的已知密文攻击方法。
二、实验环境:
系统:Windows 10
IDE:pycharm
编译语言:python
三、程序代码与结果分析:
(1)分析攻击
首先,由于异或运算的特点,采用相同密钥加密获得的密文进行异或等价于对应明文之间的异或,即:
c1=p1⊕ki
c2=p2⊕ki
c1⊕c2=p1⊕ki⊕p2⊕ki=p1⊕p2
英文句子的特点是单词之间留有空格(空字符),而空字符与小(大)写字母异或得到对应的大(小)写字母,公式表示为:
'space^'⊕(a∼z)=(A∼Z)
'space^'⊕(A∼Z)=(a∼z)
由此特点,如果某一个明文上某个位置为空字符,则对应密文的该位置与其他密文的该位置异或,得到的结果很有可能是大(小)写字母,异或的密文数目越多,其准确性就越高。如果已经确定密文的某个位置为空字符,那么将该位置与空字符异或将得到该位置的密钥key
如果获得的空字符位置足够多,便能够得到完整对应的密钥信息,可以破解相应的密文。
(2)算法实现
首先我们定义一个辅助函数用于将hex转化为int,方便后续进行异或操作
接下来我们将密文值两两进行异或操作,如果这个值是英文字母或者空格或者空字符我们将这个位置标记,每一条密文与其他所有密文统计完之后,我们统计一次记录的位置,当同一个位置被记录了8次及以上,我们将这个位置标记为可能出现空格,单个position是一个元组,这样可以过滤掉很多相同的位置,然后返回这个位置信息。这个函数是一个生成器对象,最后我们只需要list一下就可以获取所有密文中可能的空格位置。
接下来是获取密钥,同样定义一个集合用来存放密钥,我们将可能出现空格的位置的值异或上32(空格的10进制表示)将位置和结果添加到key中,之后生成一个全0的密钥,大小为密文中最长的那条大小,再针对同一个位置出现了不同的值的情况,我们可以后期微调密文,这样效果会更好,这个函数返回猜测的密钥。
下面是获取密文,我们传入密文以及密钥,将密文和密钥按位异或,然后只展示再ASCII码范围内的明文,其他用0来表示,输出猜测的明文
最后,我们调试密钥,得到了完整的正确的明文:
- 运行结果展示
输出结果:
- 实验中遇到的问题以及实验体会:
这次实验是流密码的实验,最开始拿到这个实验的时候,也是不知道如何进行,但是后面在同学的指点下,知道来英文单词异或空格这个特性,一下子茅塞顿开,开始了代码的编写,最开始输出的结果其实不是特别理想,我后面加入了同一个位置可能出现不同值的情况,这样就可以完美的输出明文。
这个实验也告诉我们,对于流密码,我们绝对不要二次使用密钥,不然是绝对不安全的。
相关资源:
https://download.csdn.net/download/dxxmsl/87699394?spm=1001.2014.3001.5503