https://aes.cryptohack.org/passwords_as_keys/
在對稱金鑰加密中,確保金鑰是隨機生成的而不是來自密碼或其他可預測的資料非常重要。因為如果金鑰具有可預測性,密碼的安全性會大幅降低,攻擊者就可能利用這一點來破解密文。
然而即使一個金鑰看起來像是隨機的,但實際上是由簡單的密碼經過雜湊函數生成的,那麼這樣的金鑰也不夠安全,甚至可能更容易被破解。
from Crypto.Cipher import AES
import hashlib
import random
# 從指定的字典文件中讀取所有單詞
#https://gist.githubusercontent.com/wchargin/8927565/raw/d9783627c731268fb2935a731a618aa8e95cf465/words
with open("/usr/share/dict/words") as f:
words = [w.strip() for w in f.readlines()] # 去除每行結尾的換行符並存入列表
# 從讀取的單詞列表中隨機選擇一個詞作為密碼
keyword = random.choice(words)
# 使用 MD5 將選定的詞轉換為 16 bytes
KEY = hashlib.md5(keyword.encode()).digest()
FLAG = ?
@chal.route('/passwords_as_keys/decrypt/<ciphertext>/<password_hash>/')
def decrypt(ciphertext, password_hash):
ciphertext = bytes.fromhex(ciphertext)
key = bytes.fromhex(password_hash)
cipher = AES.new(key, AES.MODE_ECB) # 使用指定的密鑰和 ECB 模式來建立 AES 加密器
try:
# 解密密文
decrypted = cipher.decrypt(ciphertext)
except ValueError as e:
# 如果解密過程中出現錯誤,則返回錯誤信息
return {"error": str(e)}
return {"plaintext": decrypted.hex()}
@chal.route('/passwords_as_keys/encrypt_flag/')
def encrypt_flag():
# 使用先前生成的 KEY 以 ECB 模式來建立 AES 加密器
cipher = AES.new(KEY, AES.MODE_ECB)
encrypted = cipher.encrypt(FLAG.encode())
return {"ciphertext": encrypted.hex()}
跟上一題一樣,我們可以直接從ENCRYPT_FLAG()得到 hex 格式的密文,但這題由於解密的時候還需要密碼,所以我們需要先找出密碼是甚麼。
原始碼中告訴了我們密碼是從一份單字列表中隨機選擇一個詞再經過 MD5 雜湊而成,具有隨機性。
要解題的話要先下載這份文字檔,然後改名(我改為words.txt)
放上我們得到的密文,依序讀取文字檔中的每一個單字,並進行md5雜湊來得到密鑰,接下來就依序使用密鑰進行和原始碼差不多的解密步驟。
而我們都知道flag的組成為crypto{...}所以如果解密出來的字串包含crypto{,就代表找到了對的密鑰,返回當前明文。
crypto{k3y5__r__n07__p455w0rdz?}
import hashlib
from Crypto.Cipher import AES
with open('words.txt', 'r', encoding='utf-8', errors='ignore') as f:
words = [w.strip() for w in f.readlines()]
ciphertext="c92b7734070205bdf6c0087a751466ec13ae15e6f1bcdd3f3a535ec0f4bbae66"
def decrypt(ciphertext):
ciphertext = bytes.fromhex(ciphertext)
for keyword in words:
key = hashlib.md5(keyword.encode()).digest()
cipher = AES.new(key, AES.MODE_ECB)
decrypted = cipher.decrypt(ciphertext)
try:
decrypted = cipher.decrypt(ciphertext)
if b"crypto{" in decrypted :
return decrypted.decode()
except ValueError as e:
return {"error": str(e)}
print(decrypt(ciphertext))
因為當初執行程式碼時一直發生 UnicodeDecodeError 的問題,在問了chatbot後將開啟檔案改成程式碼中的那樣後就沒有問題了~
https://ithelp.ithome.com.tw/m/articles/10332384
最近又開始沒空了,希望能寫完這部分的課程,進入到刷題的部分。