Tamevic’s Ctf-Crypto writeup@实验一"维吉尼亚密码的实现和破解"
应用密码学的第一个实验
分析
首先 关于维吉尼亚密码(Vigenere
):
它是凯撒加密的一种升级版本,即明文的每一位都是用凯撒加密(移位),但所用的密钥(移动位数)却不是相同的。在实现的过程中需要考虑加密策略,主要是对空格和标点符号的处理。(遇到标点符号和空格时密钥是否跟着移一位。如“hello world”
用“nihao”
加密,如果遇到非字母时密钥也跳一位的情况下密文为“umslc jwylr”
,而不跳一位的情况下密文为“umslc evrzq”
)我们这里加密的时候使用的策略是遇到非字母字符密钥不往后顺延。
这样来看的话,对于攻击者来说复杂度就变为了两层,一层是密钥的长度,一层是密钥的内容。
其次 关于破解思路:
古典密码的一个最重要的问题在于没有办法隐蔽文章的统计特性,维吉尼亚密码也未能避免这个问题。所以拿到一串密文,根据之前分析到的两层结构,进行试验性爆破。
这里用到的主要是拟重合指数(CI)进行试验。
CI指随机取出两个字符相同的概率
在一段正常的英文原文中CI的值是用所有的字母频率带入计算
CI≈0.065
通过和英文CI相比对,越接近这个值证明字母特性越符合英文原文。
破解时:
先猜测密钥长度,根据密钥长度对密文进行分组,把每一组中处于相同位置的密文放在一个分组里,这样一个分组内的密文都是用一个密钥进行加密的,他们的密文也会符合英文原文的重合指数。对一定范围内的密钥长度进行暴破,和CI值进行比对,求得最有可能的密钥长度。
再根据求得的密钥长度对密文进行分组,对每个分组的密钥进行暴破,具体思路和猜测密钥长度一致。看哪个密钥下重合指数比较符合英文原文,那么那个分组的密钥就是那个密钥。
最后再解密验证。
结果
加解密实现
# coding: utf-8
def encrypt(message,key):
cipher=''
j=0
for i in range (len(message)):
if key[j % len(key)].islower():
offset = ord(key[j % len(key)]) - ord('a')
else:
if key[j % len(key)].isupper():
offset = ord(key[j % len(key)]) - ord('A')
else:
offset = ord(key[j % len(key)]) - 48
j+=1
if message[i].isalpha():
if message[i].islower():
cipher += chr((ord(message[i]) - ord('a') + offset )%26 +ord('a'))
else:
cipher += chr((ord(message[i]