Vigenere密码加密解密原理

先从简单的单表代替开始提及:要知道,在CTF题中,有不少不少都是单表代替的题,好比说:python

BH=CWG=EO=IEI=;DEDEDEYapp

全部数据长成这样,神TM可以认识对吧,可是要注意,这但是CTF的比赛!因此得分模式很套路:测试

最后的答案通常都是flag{}或者FLAG{}什么的对吧加密

那么,计算一下:code

ord(‘Y’)-ord(‘}’)= - 36blog

那么,再试试:ord(‘B’)+36 = ord(‘f’)ip

因此,直接尝试一发,因此的都是36的偏移就行了,对吧ci

很简单的kaisamima对吧,本质上是个ascii码表的偏移对应,或者是本身定义的某些字符的循环对应字符串

在数据文本字符状况下足够的状况下,统计英文字频便可简单破解:由于英文中的每一个字符的出现几率是有固定的比例的(不是全部的都必定按照顺序,可是大概已经能够基本对应了)get


那么,来谈谈什么是Virginia密码:由于单表对应很容易破解,那么换成多表呢?

因此咱们肯定一种对应的方法:Virginia

这种方法须要密钥,密钥的长度是单表的数量(实际上是不一样的字符个数)

其实,多个单表的对应关系是这样,能够一个一个算,可是,根据多个单表的思想来理解会更简单

用python代码举例会更简单吧:


import string
s = string.printable[36:62]

word = 'TOBEORNOTTOBETHATISTHEQUESTION'
cipher = 'RELATIONS'
info = ''

for i in range(0,len(word)):
	info += s[(s.find(word[i])+s.find(cipher[i%len(cipher)]))%26]
print info

flag = ''
for i in range(0,len(info)):
	flag += s[(s.find(info[i])+26-s.find(cipher[i%len(cipher)]))%26]
print flag


固然,在实际应用中并不会有这么的简单:咱们不可能知道密钥是什么,甚至连密钥的长度咱们也无从知道

那么,就只能根据方法来暴力测试:

kasiski测试法,来测得密钥的长度,理论是:当字符数目足够多的话,那么有可能出现,相同的字符串被相同的偏移串加密,那么获得的结果是相同的,咱们把这些全部的可能所有统计下来,能够获得这些偏移值之间的相对距离。取他们的公共因子,就多是密钥的长度

暴力的python代码以下:

def get_len(s):
	val = []
	length = len(s)
	const = 4
	for i in range(0,length-const):
		for j in range(i+1,length):
			if s[i:i+const] == s[j:j+const]:
				val.append(j-i)
	print val

其中的const越大,说明出现的几率越低,数量会越少;const越小,出现的几率越大,数量越多

咱们须要取得一个适中的值,让val里大概有个10个数字左右,而后大概看下他们的公因数,一一分析,或者结合其余的方法来进行密钥长度的判断以及下一步计算

接下来就是肯定密钥


这里给出两个CTF样例题,能够解释说明得很明白:

https://findneo.tech/171005NuptVigenereWP/#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5

https://findneo.tech/180527suctf/#Magic