cryptopals解密之旅1-2

0x00前言
本系列文章將帶來cryptocals 這套密碼學挑戰的write-up.不同於通過上課或者看書的方式學習密碼學,這些題目來自於現在生活中一些軟件系統和密碼構造中的缺陷。
本系列每一個題的wp基本是採用如下結構:題目解釋、相關知識點講解、代碼實現及解釋,運行測試。代碼均採用python3實現,代碼實現部分是參考國外大佬ricpacca的,結合自己的理解及成文需要進行部分修改。
第一套一共有八關。

0x05
第五關
在這裏插入圖片描述
給出了明文和密鑰,要求實現repeating-key XOR,比如密鑰是ICE,則明文第一個字符與I異或,第二個字符與C異或,第三個字符與E異或,第四個字符與I異或,繼續下去。。。
通過i來控制ICE中由哪一個字符進行異或,在i=len(key),也就是i在循環中達到3時,將其置0,繼續從I開始異或,否則自增,按照I、C、E順序異或
在這裏插入圖片描述
完整代碼及執行結果如下
在這裏插入圖片描述

0x06
第6關
在這裏插入圖片描述
給出了一個文件,該文件首先經過repeating-key XOR,然後base64編碼得到
要求我們給出密鑰和明文。
並且給出了提示:
1.確定KEYSIZE,也就是密鑰的長度,比如說可以嘗試從2到40的值
2.實現一個函數,該函數功能是計算兩個字符串的漢明距
3.每次嘗試KEYSIZE時,分別計算兩個長度爲KEYSIZE的字節的串,計算其漢明距
4.選取2-3個最小漢明距離的KEYSIZE(如果選取了正確的密鑰長度,兩兩塊之間的漢明距離的值應該趨於小),在確定時可以採用一些技巧,如選取4個塊,兩兩組合計算漢明距,再除以組合數,再除以key_size,進行規格化。
5.知道KEYSIZE大小後,將密文按照KEYSIZE大小分到每個塊裏面
6.然後可以重新組合,將每個塊的第一個字節取出來重新組成一個塊,將每個塊的第二個字節取出來重新組成第二個塊。。
7.對於新組成的塊而言,此時解密就相當於是單字符的異或,我們之前已經學過怎麼處理這種情況了
8.將每個單字符異或的key組合起來就是我們要求的repeating-key XOR的key了,將明文拼接起來就是所求的完整明文了

代碼實現
漢明距是一個概念,它表示兩個(相同長度)字對應位不同的數量,我們以d(x,y)表示兩個字x,y之間的漢明距離。對兩個字符串進行異或運算,並統計結果爲1的個數,那麼這個數就是漢明距離比如011,110,其第一位和第三位不同,故漢明距爲2;而在代碼中我們是通過異或的方式計算漢明距:將其異或,然後看有多個位是1.還是上面的例子,011和110異或得到101,結果中有兩個1,所以其漢明距爲2
在這裏插入圖片描述

暴力測試key_size,根據題目的建議,取出根據key_size大小劃分的4組
然後使用迭代器itertools的combinations來組合。這個函數很簡單,看個簡單的例子就清楚了
com1=combinations(‘abcd’, 2)
for i in com1:
print i

output:
(‘A’, ‘B’)
(‘A’, ‘C’)
(‘A’, ‘D’)
(‘B’, ‘C’)
(‘B’, ‘D’)
(‘C’, ‘D’)
在代碼中計算任兩組的漢明距,然後累加,這裏一共是6組數據,所以將累加結果除以6,得到平均的漢明距,接着將其除以key_size進行規範化,得到normaliezd_distance,將其存到key_size對應的數組裏,便於與後面的數據進行比較。
有最小normalized_distance的key_size,最有可能就是真正的key_size。但是僅是可能性大而已,我們選中最有可能的三個key_size(normalized_distance最小的三個所對應的key_size)
在這裏插入圖片描述
然後分別進行測試,安裝key_size大小將密文分塊,然後將每個塊的第一個字節組成新的第一個塊,將每個塊的第二個字節組成新的第二個塊。。。然後按照單字節xor的方式來分別處理每一塊,將得到的明文拼接起來。這樣子,一共會有三個結果,然後根據之前實驗,通過字符頻率相加計算分數的方法,分數最大的則是最有可能是正確明文。
在這裏插入圖片描述
在main函數中我們首先是測試了我們計算漢明距的函數是否能正確執行
接着就是讀入密文文件,先進行base64解密,然後進行前面介紹的流程,最後返回結果
在這裏插入圖片描述

完整代碼及運行結果如下
在這裏插入圖片描述
0x07
第7關
在這裏插入圖片描述
給出了密文,該密文是由明文經AES-128 ECB模式加密後得到的內容再經過base64編碼而成。題目給了密鑰,並提示大小寫敏感,密鑰長度爲16字節
要求我們解密出明文

這裏涉及兩個知識點,一個是AES;一個是ECB,AES屬於分組密碼,密碼密碼典型的操作模式包括ECB,CBC,CFB,OFB,CTR,下文會介紹ECB,其他的操作模式在後面的題目中碰到了再介紹。

AES是高級加密標準(Advanced Encryption Standard: AES),是用以取代des的,在美國國家標準技術研究所(National Institute of Standards and Technology: NIST)在全球進行徵集的時候,AES得到了全世界很多密碼工作者的響應,先後有很多人提交了自己設計的算法。最終有5個候選算法進入最後一輪:Rijndael,Serpent,Twofish,RC6和MARS。最終經過安全性分析、軟硬件性能評估等嚴格的步驟,Rijndael算法獲勝。
Rijndael是一個分組密碼算法族,其分組長度包括128比特、160比特、192比特、224比特、256比特,密鑰長度也包括這五種長度,但是最終AES只選取了分組長度爲128比特,密鑰長度爲128比特、192比特和256比特的三個版本。本次涉及的是128比特的。
AES加密算法涉及4種操作:字節替代(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)和輪密鑰加(AddRoundKey)
在這裏插入圖片描述
AES加解密的流程,從圖中可以看出:1)解密算法的每一步分別對應加密算法的逆操作,2)加解密所有操作的順序正好是相反的。正是由於這幾點(再加上加密算法與解密算法每步的操作互逆)保證了算法的正確性。加解密中每輪的密鑰分別由種子密鑰經過密鑰擴展算法得到。算法中16字節的明文、密文和輪子密鑰都以一個4x4的矩陣表示。
1)字節代替的主要功能是通過S盒完成一個字節到另外一個字節的映射。S盒用於提供密碼算法的混淆性,S盒在分組密碼算法中,是唯一的非線性結構,其S盒的指標的好壞直接決定了密碼算法的好壞。
2)行移位:是一個4x4的矩陣內部字節之間的置換,用於提供算法的擴散性
3)列混淆:利用GF(28)域上算術特性的一個代替,同樣用於提供算法的擴散性
4)輪密鑰加:依據的原理是“任何數和自身的異或結果爲0”。加密過程中,每輪的輸入與輪子密鑰異或一次;因此,解密時再異或上該輪的輪子密鑰即可恢復
5)密鑰擴展算法比較複雜,可以參考:http://www.cs.utsa.edu/~wagner/laws/AESkeys.html

ECB模式:
ECB是最簡單的加密模式。需要加密的消息按照塊密碼的塊大小被分爲數個塊,並對每個塊進行獨立加密。
在這裏插入圖片描述
其缺點在於同樣的明文塊會被加密成相同的密文塊;因此,它不能很好的隱藏數據模式。在某些場合,這種方法不能提供嚴格的數據保密性,因此並不推薦用於密碼協議中。

題目的代碼實現:
這裏我們直接使用crypto庫的函數
查閱相關文檔可知其具體用法:https://pycryptodome.readthedocs.io/en/latest/src/cipher/classic.html#ecb-mode
在這裏插入圖片描述
AES.new(key, AES.MODE_ECB)可以實例化一個新的AES-ECB密文對象,然後調用decrypt方法即可解密
在這裏插入圖片描述
解釋一下最後一句的註釋:
我們可以直接返回解密的結果,如第三行的代碼所示;但是爲了通用性(因爲在後面的解答中還會這種這裏的代碼),使用我們在第二套第9關編寫的pkcs7_unpad方法去除填充
在main函數中就是讀入密文,先將其base64解碼,然後傳到aes_ecb_decrypt函數進行解密
完整代碼及執行結果如下
在這裏插入圖片描述

0x08
第八關
在這裏插入圖片描述
題目給了一個文件,是16進制編碼的一些字符串,其中有一個字符串是AES-ECB加密過的,要求我們找出來。
解題最關鍵的一步就是要知道:由於ECB模式的特點,同樣的明文塊會被加密成相同的密文塊。所以我們可以通過查找加密字符串中是否有相同的密文塊,來判斷是否爲ECB模式。如果都有相同的密文塊(一般是不會出現這種情況的,因爲如果有這種模式,那是非常危險的,這也是爲什麼ECB非常不被推薦使用的原因),則相同密文塊最多的那個字符串是ECB模式加密得到的。

計算重複塊的次數
在這裏插入圖片描述
計算每一串密文的重複塊數, 返回有最多重複塊的密文,這最可能是AES-ECB加密得到的
在這裏插入圖片描述
完整代碼及執行結果如下
在這裏插入圖片描述

參考:
1.https://cryptopals.com/sets/1
2.https://github.com/ricpacca/cryptopals

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章