先从简单的单表代替开始提及:要知道,在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
咱们须要取得一个适中的值,让val里大概有个10个数字左右,而后大概看下他们的公因数,一一分析,或者结合其余的方法来进行密钥长度的判断以及下一步计算
接下来就是肯定密钥
这里给出两个CTF样例题,能够解释说明得很明白:
https://findneo.tech/171005NuptVigenereWP/#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5