https://cryptohack.org/courses/symmetric/ecbcbcwtf/
題目告訴我們,題目給的加密器會進行 CBC 加密,而解密器則會進行 ECB 解密。
看到題目想說 WTF,在說甚麼,怎麼可能可以用 ECB 解密 CBC 加密後的內容,後來才發現原來指的是題目提供的加解密器。
from Crypto.Cipher import AES
import os
from flask import Flask
KEY = ?
FLAG = ?
chal = Flask(__name__)
@chal.route('/ecbcbcwtf/decrypt/<ciphertext>/')
def decrypt(ciphertext):
ciphertext = bytes.fromhex(ciphertext)
# 使用ECB模式建立一個AES密碼對象
cipher = AES.new(KEY, AES.MODE_ECB)
try:
decrypted = cipher.decrypt(ciphertext)
except ValueError as e:
return {"error": str(e)}
return {"plaintext": decrypted.hex()}
@chal.route('/ecbcbcwtf/encrypt_flag/')
def encrypt_flag():
# 生成16字節的隨機初始化向量(iv)
iv = os.urandom(16)
# 使用CBC模式建立一個AES密碼對象
cipher = AES.new(KEY, AES.MODE_CBC, iv)
# 加密FLAG(先將字符串編碼為字節)
encrypted = cipher.encrypt(FLAG.encode())
# 將iv和加密後的數據連接,並轉換為十六進制字符串
ciphertext = iv.hex() + encrypted.hex()
# 返回完整的密文
return {"ciphertext": ciphertext}
先來分別了解一下ECB加密和CBC加密的不同
* 將明文按區塊大小切分,並使用同樣的金鑰加密切分好的明文分組。
* 每個區塊獨立加密,沒有相互關聯。
* 相同的明文區塊會產生相同的密文區塊。
示意圖:
文字說明:
第一個區塊的加密:
* 兩者都使用相同的區塊加密演算法(如AES)來加密固定大小的明文區塊。
* 加密和解密過程都依賴相同的對稱密鑰。
也就是下圖中黃框的部分
part1: 切分密文
from pwn import *
#ciphertext是按下網頁ENCRYPT_FLAG()區的submit 會得到的隨機密文。
ciphertext="993d1f37b5b933dcdad3a825889aeb1341fd1f00c8408b19d5db6752c133ba622531e7bdf5ef43c19f97960020304894"
# 從原始碼中我們可以知道,我們所獲得的密文其實是iv+加密後的數據。
# 又 1 block= 16 bytes= 32 個hex字符,所以可以將密文切分成 iv, cipher1, cipher2
iv= ciphertext[:32]
cipher1=ciphertext[32:64]
cipher2=ciphertext[64:128]
part2: 還原經過AES加密法的密文塊(cipher、cipher2)
因為在這題中ECB和CBC都同樣使用AES加密演算法來加密固定大小的明文區塊,且加密和解密過程都依賴相同的對稱密鑰。
兩者的加密過程只差在CBC輸入的明文塊會與前一個密文塊進行XOR運算,所以可以利用題目給的ECB解密器來還原CBC XOR運算後的密文。
#印出cipher1和cipher2後,分別將他們丟到網站上的DECRYPT(CIPHERTEXT),得到cipher1_decrypt、cipher2_decrypt
print(cipher1)
print(cipher2)
cipher1_decrypt="fa4f6647c1d648efb9b1f710fdf98026"
cipher1_decrypt="1ec96930f924d428e2844673e0129b1f"
part3: 還原經過XOR運算的密文塊(cipher1_decrypt、cipher1_decrypt)
# cipher1_decrypt= iv ^ plain1 , plain1 = iv ^ plain1 ^ iv = cipher1_decrypt^ iv
# cipher2_decrypt= cipher1 ^ plain2, plain2 = cipher2_decrypt ^ cipher1
plain1= xor(bytes.fromhex(iv),bytes.fromhex(cipher1_decrypt))
plain2= xor(bytes.fromhex(cipher2_decrypt),bytes.fromhex(cipher1))
print((plain1+plain2).decode())
crypto{3cb_5uck5_4v01d_17_!!!!!}
https://ithelp.ithome.com.tw/m/articles/10334313
https://ithelp.ithome.com.tw/articles/10249953
https://jainl28patel.github.io/posts/Symmetric_Cryptography_CryptoHack/
應該會把SYMMETRIC CRYPTOGRAPHY的題目寫完再補一些其他平題的題目練習。