1. 程式人生 > >Vigenere密碼加密解密原理

Vigenere密碼加密解密原理

先從簡單的單表代替開始說起:要知道,在CTF題中,有很多很多都是單表代替的題,比如說:

BH=CWG=EO=IEI=;DEDEDEY

所有資料長成這樣,神TM能夠認識對吧,但是要注意,這可是CTF的比賽!所以得分模式很套路:

最後的答案一般都是flag{}或者FLAG{}什麼的對吧

那麼,計算一下:

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

那麼,再試試:ord(‘B’)+36 = ord(‘f’)

所以,直接嘗試一發,所以的都是36的偏移就好了,對吧

很簡單的kaisamima對吧,本質上是個ascii碼錶的偏移對應,或者是自己定義的某些字元的迴圈對應

在資料文字字元情況下足夠的情況下,統計英文字頻即可簡單破解:因為英文中的每個字元的出現概率是有固定的比例的(不是所有的都一定按照順序,但是大概已經可以基本對應了)

那麼,來談談什麼是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樣例題,可以解釋說明得很明白: