iT邦幫忙

2024 iThome 鐵人賽

0
Security

密碼學小白的學習之路系列 第 31

[Day 30] 題目(Symmetric-11)

  • 分享至 

  • xImage
  •  

ECB CBC WTF

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加密的不同

ECB:電子密碼本模式

* 將明文按區塊大小切分,並使用同樣的金鑰加密切分好的明文分組。
* 每個區塊獨立加密,沒有相互關聯。
* 相同的明文區塊會產生相同的密文區塊。
https://i.imgur.com/YVlx6qj.png

CBC:密碼分組連結模式

  • 每個區塊的加密結果依賴於前一個密文區塊。
  • 第一個區塊會使用初始向量(IV)進行加密。
  • 相同的明文區塊因為前一區塊的影響,即使加密相同的數據,也會產生不同的密文,大大增加了安全性。
    https://i.imgur.com/5Hn8Bif.png

CBC過程詳細介紹:

示意圖:
https://ithelp.ithome.com.tw/upload/images/20240915/20168165oYt1AsRvIZ.png
文字說明:
第一個區塊的加密:

  • IV(初始化向量)與 Plaintext1(第一個明文區塊)進行XOR運算。
  • XOR的結果通過加密算法(如AES)進行加密。
  • 加密的輸出成為 Ciphertext1(第一個密文區塊)。
    後續區塊的加密:
  • Ciphertext1 用於下一個加密步驟。
  • Plaintext2(第二個明文區塊)與 Ciphertext1 進行XOR運算。
  • XOR的結果再次通過加密算法加密。
  • 加密的輸出成為 Ciphertext2(第二個密文區塊)。
    過程重複:
  • 直到所有的明文區塊都被加密。
  • 每個後續的明文區塊都與前一個密文區塊進行XOR,然後加密。

ECB與CBC的相同之處

* 兩者都使用相同的區塊加密演算法(如AES)來加密固定大小的明文區塊。
* 加密和解密過程都依賴相同的對稱密鑰。
也就是下圖中黃框的部分
https://ithelp.ithome.com.tw/upload/images/20240915/201681658wqt1QiVA4.png
https://ithelp.ithome.com.tw/upload/images/20240915/20168165Bj310MPVIT.png

解題思路

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的題目寫完再補一些其他平題的題目練習。


上一篇
[Day 29] 題目(Symmetric-10-2)
系列文
密碼學小白的學習之路31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言