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樣例題,可以解釋說明得很明白: