2018/05/02

[Cryptography] pycrypto筆記: 使用AES區塊加密之CBC和CTR工作模式

在此紀錄學習Coursera上學習密碼學(Cryptography)的一些心得。

首先,在第二週的課程,Dan Boneh教授介紹了區塊加密(Block Ciphers)的概念,特別是進階加密標準(AES, Advanced Encryption Standard)中的兩個工作模式:

1. 密碼塊連結(CBC, Cipher-block chaining): 利用隨機產生的初始向量(IV, Initialization Vector)與明文(Plaintext)區塊做互斥邏輯運算,再透過金鑰(Key)加密區塊,再把IV取代成加密區塊結果,依序加密剩下明文區塊。但缺點是,最後一個明文區塊有dummy padding的問題。假設明文長度剛好為16bytes的倍數,其尾端還得加上由0x16 * 16組成的16 bytes dummy padding。



2. 計數器模式(CTR, Counter mode): 利用隨機產生的初始向量(IV, Initialization Vector)加上依序增加的計數器所組成的區塊,加密後,再對每個相對應的明文區塊同時做加密的動作。優點是可以利用平行運算增加速度,也是相較於CBC模式,推薦使用CTR模式。

在實作上,這次採用pycrypto來實現;且在python 2.7的環境下執行。

先安裝pycrypto在系統上,我是在Ubuntu 16.04的VM下安裝。去官網下載最新版(v2.6.1)。

下載後解壓縮,然後下安裝指令:
$ python setup.py install


完成後就可以先用一個簡單的小範例來測試:
from Crypto.Cipher import AES

print("---This is an example for Crypto---")
obj = AES.new('This is a key456', AES.MODE_ECB)
message = "The answer is no"
ciphertext = obj.encrypt(message)
print("ciphertext is '%s'" %ciphertext)
obj2 = AES.new('This is a key456', AES.MODE_ECB)
de_ciphertext = obj2.decrypt(ciphertext)
print("de_ciphertext is '%s'" %de_ciphertext)

其輸出會看到


接著,在第二周的程式作業中,老師給了四個密文(2 CBC加密、2 CTR加密)及對應的2把金鑰,要我們試著把明文解密出來。

Question 1

CBC key: 140b41b22a29beb4061bda66b6747e14
CBC Ciphertext 1: 4ca00ff4c898d61e1edbf1800618fb2828a226d160dad07883d04e008a7897ee2e4b7465d5290d0c0e6c6822236e1daafb94ffe0c5da05d9476be028ad7c1d81
--------------------------------------------------------------------------------

Question 2

CBC key: 140b41b22a29beb4061bda66b6747e14
CBC Ciphertext 2: 5b68629feb8606f9a6667670b75b38a5b4832d0f26e1ab7da33249de7d4afc48e713ac646ace36e872ad5fb8a512428a6e21364b0c374df45503473c5242a253
--------------------------------------------------------------------------------

Question 3

CTR key: 36f18357be4dbd77f050515c73fcf9f2
CTR Ciphertext 1: 69dda8455c7dd4254bf353b773304eec0ec7702330098ce7f7520d1cbbb20fc388d1b0adb5054dbd7370849dbf0b88d393f252e764f1f5f7ad97ef79d59ce29f5f51eeca32eabedd9afa9329
--------------------------------------------------------------------------------

Question 4

CTR key: 36f18357be4dbd77f050515c73fcf9f2
CTR Ciphertext 2: 770b80259ec33beb2561358a9f2dc617e46218c0a53cbeca695ae45faa8952aa0e311bde9d4e01726d3184c34451

在此並沒有要直接把答案貼上,而且Google一下應該也很多資料,但有幾個值得注意的重點。
1. 密文的前16 bytes為IV,在解密過程中,要把IV從密文中移除,特別是在CTR模式下,如果沒把IV移除再解密,會無法得到正確的結果
2. CBC解密後,要再把尾端的padding移除,若是解密正確,其尾端應該會是'0808080808080808',類似這種同樣重複的數字
3. CBC使用的AES物件為,特別注意要把密文前面的IV代入:

AES.new(CBC_key.decode('hex'), AES.MODE_CBC, cbc_nonce1.decode('hex'))
4. CTR使用的AES物件為,特別注意要把密文前面的IV做處理後,以Crypto.Util.Counter的物件ctr1代入:

AES.new(CTR_key.decode('hex'), AES.MODE_CTR, counter=ctr1)

整體來說,雖然花了約一個下午的時間解密這四個問題,但是經過實作後,會對CBC和CTR有深刻的理解。

沒有留言:

張貼留言