維基少年:樹莓派/樹莓派謎機


政府通訊總部和樹莓派基金會 CC-BY-SA 4.0 ![]()
基於樹莓派 OctoPi 教程:https://projects.raspberrypi.org/en/projects/octapi-brute-force-enigma
謎機是一種用於加密和解密資訊的裝置。它是在20世紀初開發的,在第二次世界大戰期間被德國人廣泛用於編碼他們的軍事通訊。
謎機最出名的是被阿蘭·圖靈和他在布萊切利莊園的團隊破解,他們開發了破譯謎機密碼的技術。這在第二次世界大戰中盟軍的勝利中發揮了至關重要的作用,因為它使他們能夠攔截並解碼德國人傳送的重要資訊。
謎機是如何工作的? 在 YouTube 上
謎機由以下部分組成
- 一個用於輸入資訊的鍵盤
- 一系列執行加密和解密的轉子
- 一個反射器,將電流反射回轉子,方向相反
轉子可以設定在不同的位置,從而產生大量可能的組合,使得攻擊者很難解碼資訊。
檢視你的謎機設定表,你會發現今天的設定如下
| 轉子 | 環設定 | 插線板設定 | 轉子起始位置 |
|---|---|---|---|
| IV I V | 20 05 10 | SX KU QF UN JG TC LA WM OB ZF | FNZ |
這裡有一條秘密資訊:GON XXLXYFQNZIK
- 開啟 Python 3,然後開啟名為
decrypt.py的檔案 - 在
chosen_rotors旁邊的綠色引號''內輸入所選轉子。 - 現在在
rotor_start旁邊的綠色引號''內輸入轉子起始位置的字母。 - 在
message_key旁邊的綠色引號''內輸入資訊金鑰GON。 - 輸入明文,即秘密資訊
XXLXYFQNZIK。 - 透過按 F5 鍵執行程式(如果提示儲存,請選擇“是”)。
使用相同的謎機設定,但不要忘記更改資訊金鑰:LJE OIVGWVHOVHKAU
- 開啟 Python 3,然後開啟名為
encrypt.py的檔案 - 再次從設定表中輸入所選轉子,以及轉子起始位置。
- 在
message_key旁邊的綠色引號' '內輸入資訊金鑰BFR。 - 執行程式並檢查它是否有效——對於明文
RASPBERRYPI,生成的密文應該是XXLXYFQNZIK。
現在是時候加密你自己的資訊了!
- 選擇不同的三個字母的
message_key並輸入。 - 選擇不同的明文資訊並輸入。確保沒有空格!
- 執行程式,然後記下加密的金鑰和密文,並將它們交給其他人解密。
解密這條資訊:GED HYZFQOOVVBBKBWPDZLSL
你需要知道謎機設定才能解密資訊!
這是今天的設定。不幸的是,有人在轉子設定上灑了墨水 😟
| 轉子 | 環設定 | 插線板設定 | 轉子起始位置 |
|---|---|---|---|
| 21 15 16 | KL IT PQ MY XC NF VZ JB SH OG | POW |
字謎是你在知道明文和密文的情況下才能知道的資訊。
字謎:WEATHER
密文:VZTLMPU
如果你知道字謎和部分設定,你能使用暴力破解攻擊解密這條資訊嗎?
VZTLMPUSLKTEXYWZWKXDOTT
- 開啟 Python 3,然後開啟名為
bruteforce.py的檔案。 - 輸入字謎和相應的密文。
- 執行暴力破解攻擊,以找到轉子和資訊金鑰。
- 現在開啟之前使用過的
decrypt.py程式。 - 輸入
rotor start設定,這次你還需要從設定表中輸入環和插線板設定。 - 在暴力破解攻擊中找到的
chosen rotors中輸入。 - 這次我們已經知道解密的訊息金鑰。找到這行程式碼:
decrypted_message_key = machine.process_text(message_key)。
將其更改為decrypted_message_key = '???',其中???是在暴力破解攻擊中找到的三個字母的金鑰。
- 秘密資訊是什麼?
DHPCMHCQ PXE
18/05/18
ZOC EJDTLFHR BT UKW.
本教程使用Brian Neal 編寫的 py-enigma 模組來提供 Enigma 機器功能。
您可以透過在
終端中執行此命令在您的 Raspberry Pi(或您的計算機)上安裝 py-enigma 的副本
sudo pip3 install py-enigma
維基少年第二次世界大戰一書中有一節介紹 Enigma 機器,其中詳細介紹了它的工作原理。
瞭解 Enigma 機器的最佳場所是參觀英國米爾頓凱恩斯附近的 布萊切利莊園。
模仿遊戲(2014)是一部由本尼迪克特·康伯巴奇主演的電影,他扮演了破譯 Enigma 機器的阿蘭·圖靈。這部電影的年齡分級為 12 級(在美國為 PG-13 級),因此適合年齡較大的兒童和成年人。
樹莓派基金會推薦傳記Dilly — The Man Who Broke Enigmas(2010,ISBN 9781906447151)由 Mavis Batey 撰寫。這本書講述的是二戰期間英國首席密碼破譯員阿爾弗雷德·迪爾溫·諾克斯的故事。
本教程的原始 PDF 檔案可在維基共享資源上獲得
from enigma.machine import EnigmaMachine
chosen_rotors = '' # Type a space between each rotor e.g. V IV I
rotor_start = ''
message_key = ''
plaintext = 'RASPBERRYPI' # The message you want to encrypt
print("You started with message key " + message_key + " and plaintext " + plaintext)
# Set up the Enigma machine
machine = EnigmaMachine.from_key_sheet(
rotors=chosen_rotors,
reflector='B',
ring_settings='20 5 10',
plugboard_settings='SX KU QP VN JG TC LA WM OB ZF')
# Set the initial position of the Enigma rotors
machine.set_display(rotor_start)
# Encrypt the message key (the three letters you chose)
encrypted_message_key = machine.process_text(message_key)
print("The encrypted message key is " + encrypted_message_key)
# Set the rotor start position to the UNENCRYPTED message key
machine.set_display(message_key)
# The result
ciphertext = machine.process_text(plaintext)
print("The cipher text is: " + ciphertext)
from enigma.machine import EnigmaMachine
chosen_rotors = '' # Type a space between each rotor e.g. V IV I
rotor_start = ''
message_key = ''
plaintext = '' # The message you want to decrypt
print("You started with message key " + message_key + " and plaintext " + plaintext)
# Set up the Enigma machine
machine = EnigmaMachine.from_key_sheet(
rotors=chosen_rotors,
reflector='B',
ring_settings='20 5 10',
plugboard_settings='SX KU QP VN JG TC LA WM OB ZF')
# Set the initial position of the Enigma rotors
machine.set_display(rotor_start)
# Decrypt the message key
decrypted_message_key = machine.process_text(message_key)
print("The decrypted message key is " + decrypted_message_key)
# Set the rotor start position to the DECRYPTED message key
machine.set_display(decrypted_message_key)
# The result
ciphertext = machine.process_text(plaintext)
print("The cipher text is: " + ciphertext)
cribtext = ""
ciphertext = ""
# All possible combinations of rotors
rotors = [ "I II III", "I II IV", "I II V", "I III II",
"I III IV", "I III V", "I IV II", "I IV III",
"I IV V", "I V II", "I V III", "I V IV",
"II I III", "II I IV", "II I V", "II III I",
"II III IV", "II III V", "II IV I", "II IV III",
"II IV V", "II V I", "II V III", "II V IV",
"III I II", "III I IV", "III I V", "III II I",
"III II IV", "III II V", "III IV I", "III IV II",
"III IV V", "IV I II", "IV I III", "IV I V",
"IV II I", "IV II III", "IV I V", "IV II I",
"IV II III", "IV II V", "IV III I", "IV III II",
"IV III V", "IV V I", "IV V II", "IV V III",
"V I II", "V I III", "V I IV", "V II I",
"V II III", "V II IV", "V III I", "V III II",
"V III IV", "V IV I", "V IV II", "V IV III" ]
def find_rotor_start( rotor_choice, ciphertext, cribtext ):
from enigma.machine import EnigmaMachine
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
machine = EnigmaMachine.from_key_sheet(
rotors=rotor_choice,
reflector='B',
ring_settings='21 15 16',
plugboard_settings='KL IT PQ MY XC NF VZ JB SH OG')
# Search over all possible rotor starting positions
for i in range(len(alphabet)): # search for rotor 1 start position
for j in range(len(alphabet)): # search for rotor 2 start position
for k in range(len(alphabet)): # search for rotor 3 start position
# Generate a possible rotor start position
start_pos = alphabet[i] + alphabet[j] + alphabet[k]
# Set machine initial starting position and attempt to decrypt
machine.set_display(start_pos)
plaintext = machine.process_text(ciphertext)
#print("Plain: " + plaintext + ", Crib: " + cribtext)
# Check if decrypted text is the same as the crib text
if (plaintext == cribtext):
return( rotor_choice, start_pos )
return( rotor_choice, "null" )
print("Brute force crypt attack on Enigma message " + ciphertext)
print("Crib text " + cribtext )
# Try all rotor settings
for rotor_setting in rotors:
print("Trying rotors " + rotor_setting)
rotor_choice, start_pos = find_rotor_start( rotor_setting, ciphertext, cribtext )
if (start_pos != "null"):
print("Machine setting found!")
print("Rotors: " + rotor_choice)
print("Message key: " + start_pos)
print("Using crib " + cribtext)
exit(0)