一、機械密碼學簡介
在20世紀,隨着機械密碼機的出現,密碼的複雜性呈爆炸式增長。加密或解密信息的人不再需要理解密碼原理即可操作,過去需要數小時才能完成加密的信息現在幾乎可以瞬間完成。
無線電通信在第二次世界大戰期間成爲不可或缺的工具,但由於信號極易被截獲,強大的加密技術變得至關重要。德國軍方選擇採用發明家亞瑟·謝爾比烏斯(Arthur Scherbius)設計的恩尼格瑪密碼機(Enigma),其加密強度在當時堪稱空前。
當按下恩尼格瑪鍵盤上的字母鍵時,電信號會流入一個擾頻盤(轉子)。該轉子有26個輸入和26個輸出,內部以隨機方式連接——例如,輸入1的信號可能從輸出14離開。信號會依次通過3個這樣的轉子,隨後被反射,再次反向通過相同的3個轉子,最終在燈板上顯示加密後的字母。
僅看這一過程,恩尼格瑪似乎只是一個單字母替換密碼。但其強大之處在於轉子會旋轉:每按一次鍵,第一個轉子便轉動一格;當它轉到特定凹槽位置時,會帶動第二個轉子轉動一格,而第二個轉子最終會帶動第三個轉子轉動。這使得恩尼格瑪成爲多字母替換密碼機,能夠循環使用17,576種(26³種)不同的替換字母表後才重複模式。
爲增強安全性,恩尼格瑪還允許通過接線板交換鍵盤上最多10對字母的接線,且轉子可拆卸並按6種不同順序排列。結合轉子的17,576種初始旋轉位置,機器的總初始配置組合超過15,000,000,000,000,000,000,000(1.5×10²²)種。
只要將機器設置爲正確的初始配置,即可解密使用相同設置加密的信息,因此初始配置即爲密鑰。德國軍隊每日更換密鑰,並每月分發絕密密碼本,其中包含恩尼格瑪的初始設置信息。
MECHANISED CRYPTOGRAPHY
二、Enigma的內部構造及工作原理
2.1 Enigma的內部構造
SCRAMBLERS(轉子):轉子是Enigma的核心部分,單一轉子的加密方式非常簡單,它只使用了一種初級的替換式密碼。比如說,E鍵對應的管腳可能會連到同一個轉子另一面的T觸點。使恩尼格瑪機的加密變得複雜的是多個轉子的同時使用,一般在一臺恩尼格瑪機內有3個或4個轉子,在輸入信息的同時轉子還會轉動,這就產生了一種安全得多的加密方式。
當被放進恩尼格瑪機後,一個轉子可以有26種排列方法。
LAMPBOARD(指示器):顯示明文字母鍵入後所對應的密文字母。
KEYBOARD(鍵盤):輸入明文。
PLUGBOARD(接線板):可最多交換10對在接線板上連接的字母對。
2.2 Enigma的工作原理
密文轉換成明文的步驟:
鍵入密文字母輸入電信號,轉子轉動。電信號通過接線板後被替換爲設置好的對應字母信號位。
電信號依次通過3個的轉子(通常標記爲I、II、III)對信號進行替換,每個轉子的內部接線隨機(如輸入1→輸出14)。
電流到達第三個轉子後,進入反射器。反射器將信號反向導回,但路徑與進入時不同(如輸入14→輸出9)。
反射後的信號反向通過三個轉子(順序變爲III→II→I),再次進行三次替換後得到明文,且轉子位置與正向時相同(因爲沒有再次按鍵)。
注:轉子組具有進位機制,每次按鍵後,僅第一個轉子轉動。第二個轉子要等第一個轉子轉動26次之後纔會轉動,屆時依舊僅第二個轉子轉動,以此類推。即每次鍵入時,只有一個轉子轉動。
三轉子組合需經過26×26×26=17576次按鍵後纔會恢復初始位置,形成長週期多表替換。
三、小試牛刀
密文:ZYDNI
電信號在到達反射器前,轉子的輸入位是上層字母(輸出位下層)。在到達反射器後,轉子的輸入位變爲下層字母(輸出位上層)。
反射器的輸入位爲下層字母,輸出位爲上層。
轉子在按鍵按下後就開始轉動,在電信號到達之前就轉動完成了。
鍵入第一個字母"Z",轉子1轉動。(若有多個轉子,也只有1轉動)
電信號"Z"進入第一個轉子的輸入位爲26對應字母"A"(上層),"A"在轉子中的輸出位爲4。
也就是說電信號會進入反射器的輸入位4對應字母"H"(下層),"H"在反射器中的輸出位爲8。
反射時,電信號進入轉子的輸入位8對應字母"V"(下層),"V"在轉子中的輸出位爲21。
輸出時,21對應的字母是"U",即第一個明文字母爲"U"。(本題沒有接線板在輸入輸出時轉換字母)
鍵入第二個密文字母"Y"後,轉子1再次轉動(若有多個轉子,其他依舊不轉,直到1轉滿26次後,轉動盤變爲第二個,依此類推),其他步驟如上。最後"Y"的明文字母爲"L"。
明文:ULTRA
四、代碼實現及說明
Github倉庫鏈接:https://github.com/ZzySlhbcf/Cypher-Decoder
4.1 轉子
該對象在創建時需要兩個變量,一爲下層字母序列,二爲初始需要移動幾次或初始位置的第一個字母(轉子在初始化時即完成初始傳動)。
由上文我們可以知道,轉子由上下兩層字母組成。按道理來說,我們應該創建一個元組列表如"[(A,Z),(B,C)]"。這種方法是可行的,但是不難發現如果轉子初始沒有發生移動的話,上層的字母序列永遠是"A-Z",我們只需要對其ASCII碼值進行簡單運算就可以獲得移動後的上層字母序列。
向下傳遞時輸出字母:chr((輸入數組下標+初始化轉動位數+工作時轉動位數) % 26+65(大寫字母的起始ASCII))
向上傳遞時輸出下標:(26-初始化轉動位數-工作時轉動位數+ord(反射器接收到的下標所對應的字母)-65) % 26
Move_Scrambler():該方法用於初始化轉子和工作時轉動轉子,工作轉動後將轉動次數加一。
Check_Round():該方法用於檢查轉子是否轉動26次,未到26次則返回值爲1,表示該轉子可進行1次轉動。到26次,則將轉動次數歸零且將轉子鎖定,返回值爲0。
Get_Down_Index():該方法接收向下傳輸(未到反射器之前)時的輸入下標,將其轉換爲輸出的下標。
Get_Up_Index():該方法接收向上傳輸(到達反射器之後)時的輸入下標,將其轉換爲輸出的下標。
4.2 ENIGMA解密裝置
該對象在創建時需要四個變量,一爲轉子序列組,二爲反射器序列,三爲密文序列,四爲接線板字典。
着重講一下Decoder()方法,遍歷密文序列。先將密文字母過一遍接線板字典,後面該字母遍歷轉子組。遍歷時轉子組轉動標記初始化爲1,對應標記的轉子需要自檢,自檢時激活轉子,自檢通過該轉子繼續轉動;否則該轉子停止轉動,轉子組轉動標記後移。轉子自檢後,密文字母按先下後上的方式通過轉子組,得到對應的明文字母。
4.3 主函數
Scrambler1-3:轉子序列,若不需要初始化移動,則不需要輸入第二個變量。
Reflextor:反射器序列。
Sentence:密文序列。
Plugboard:接線器字典。
Scrambler_list:轉子排列順序,若只有一個轉子則列表內只有Scrambler1。
更多遊戲資訊請關註:電玩幫遊戲資訊專區
電玩幫圖文攻略 www.vgover.com