iT邦幫忙

2024 iThome 鐵人賽

DAY 28
0
Security

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

[Day 28] 題目(Symmetric-10-1)

  • 分享至 

  • xImage
  •  

ECB Oracle

https://cryptohack.org/courses/symmetric/ecb_oracle/

題意:

ECB 是最簡單的加密模式,每個明文區塊會獨立加密。在這裡,你的flag 會被加到所輸入的內容後面,然後再一起加密。

點入題目給的網址後,先來看一下原始碼。

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
KEY = ?
FLAG = ?
@chal.route('/ecb_oracle/encrypt/<plaintext>/')
def encrypt(plaintext):
    plaintext = bytes.fromhex(plaintext)
    #這裡的 plaintext 與 FLAG 的編碼形式進行串接後,使用 pad 函數來填充,使其長度成為AES的區塊大小(16 bytes)的倍數。
    padded = pad(plaintext + FLAG.encode(), 16) 
    cipher = AES.new(KEY, AES.MODE_ECB)
    try:
        encrypted = cipher.encrypt(padded)
    except ValueError as e:
        return {"error": str(e)}

    return {"ciphertext": encrypted.hex()}

這題中很重要的概念是填充模式(Padding),也就是在區塊加密中,當明文的長度不是區塊大小的整數倍時,用額外的資料填滿最後一個不完整的區塊,以確保所有區塊的大小一致。關於填充模式晚點寫一篇小介紹。

從原始碼中我們可以知道區塊大小為16bytes。
1 bytes = 8bits = 2個hex字符(因為 2^4=16,所以一個hex字符4bits)
16 bytes = 32個hex字符
需要注意的是這題中不管是加密後還是解密後的字元格式都是hex

如何向題目的網域發送請求

從原始碼中的

@chal.route('/ecb_oracle/encrypt/<plaintext>/')

得出進行加密的網址為"https://aes.cryptohack.org/ecb_oracle/encrypt/"
再加上我們要加密的hex字串
使用request的方法就可以向網頁端發送請求了。

如何推測出flag的長度

上面提到plaintext與FLAG的編碼形式進行串接後,會使用pad函數來填充使長度成為16 bytes的倍數。
所以接下來簡單寫個程式碼來判斷flag的長度。
從程式運行的結果可以看到當str從 6 bytes 變成 7 bytes時, block 從 32 bytes 變成 48 bytes。
所以flag的長度為32-6=26bytes,而因為byte顯示時會有一個b'的前綴,所以實際的flag為25bytes。
(因為當 str=7 bytes時,plaintext+FLAG > 32 bytes,所以被填充為48bytes)
https://ithelp.ithome.com.tw/upload/images/20240903/20168165F1ZKwVrwp8.png

接下來內容有點太多分兩部分發好了,今天先這樣,明天再補剩下的。


上一篇
[Day 27] 題目(Encoding Challenge) & 凱薩密碼與 rot 13
下一篇
[Day 29] 填充模式(Padding)
系列文
密碼學小白的學習之路31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言