cryptopals解密之旅1-1

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

0x01
我們先來看第一關
1.1
在這裏插入圖片描述
第一題
在這裏插入圖片描述
題目要求我們將十六進制轉爲base64, 將十六進制4927…,base64編碼成SSdt…

我們知道,Base64是網絡上最常見的用於傳輸 8bit 的編碼方式之一,Base64就是一種基於64個可打印字符來表示二進制數據的方法
在一些網絡傳送渠道,有時候有些的字節字符不能被支持.比如圖片的二進制流的每個字節不可能全部是可見字符,這種情況下傳送不了.而Base64的機制就能很好解決這種問題,它不改變原來的協議,在原來的基礎做一種擴展,基於64個可打印字符來表示二進制.
再者,有時候我們通過記事本去打開一些圖片或者應用程序,會得到一大堆看不懂的亂碼,因爲二進制文件裏面有很多無法顯示和打印的字符.所以如果要讓記事本能夠處理二進制數據,就可以使用Base64來進行轉碼,將不可見的轉成可見的.

我們先來學習base64編碼的原理
我們拿到一串字符,比如 abcdef.
1.按ASCII碼編碼.
2.將字符串按字節數分開,每三個字節爲一組. 3 byte * 8 bit === 24bit.
3.在這組中,將24位數據按照每6位爲一組,再次分成4組.
4.然後將這四組的6位數的高位各補兩個0,將其轉爲十進制數.
5.進行查表,得到對應的字符,就是對應的Base64轉化的字符.
在這裏插入圖片描述

一個簡單的例子如下:
在這裏插入圖片描述
那麼問題來了,如果原始數據的位數不是3的整數倍怎麼辦?如果最後剩下兩個輸入數據,在編碼結果後加1個“=”;如果最後剩下一個輸入數據,編碼結果後加2個“=”;如果沒有剩下任何數據,就什麼都不要加,這樣纔可以保證資料還原的正確性。或者說分成6位一組後,最後一組沒有到6位怎麼辦?此時需要填充一個=或者兩個=。 具體情況我們會在代碼實現部分分析。
可見,編碼後的數據比原始數據略長,爲原來的4/3

記下來是代碼的實現
定義Status類,一個16進制佔4位,因爲是以6位爲一組,所以讀取1個16進制字符後的轉換狀態的可能情況有三種
在這裏插入圖片描述
如果是新的一組,將一個16進制字符的4位放入,那麼還需要兩個bit進行填充。接着將status設置爲填充2位的情況
在這裏插入圖片描述
如果需要填充2位,則填充後該組就完整了,就可以通過編碼表進行對應編碼了,編碼後將其附加到編碼後字符串末尾。接着將status設置爲填充4位的情況
在這裏插入圖片描述
如果需要填充4位,則填充後該組就完整了,就可以通過編碼表進行對應編碼了,編碼後將其附加到編碼後字符串末尾。接着將status設置爲處理新一組的情況

在這裏插入圖片描述

如果6位一組的字符串還需要填充2個bit話,我們就在最後一組加上2個0,這種情況下在最後轉爲base64的時候需要填充=
以給aa進行base編碼爲例:
aa的二進制爲:01100001 01100001
分成6位一組:011000 010110 000100(紅色的是補上的0)
轉爲10進制:24 22 4
查表,轉爲base64,爲:Y W E =(=是填充上的)
代碼如下
在這裏插入圖片描述
如果6位一組的字符串還需要填充4個bit話,我們就在最後一組加上4個0,這種情況下在最後轉爲base64的時候需要填充==
舉個例子,以給a進行base64編碼爲例
在這裏插入圖片描述
代碼如下
在這裏插入圖片描述

完整的代碼如下以及執行結果如下:
在這裏插入圖片描述
打印出了相應的信息
Python assert(斷言)用於判斷一個表達式,在表達式條件爲 false 的時候觸發異常。我們可以用斷言來測試
在這裏插入圖片描述
完整代碼如下
在這裏插入圖片描述
運行如圖
在這裏插入圖片描述
沒有錯誤。
如果將hex_to_base64的字符串的第一個4刪去,再次執行
在這裏插入圖片描述
則會報AssertionError
說明我們成功手動實現了base64編碼的算法

0x02
第二關
在這裏插入圖片描述
要求寫一個函數對兩個16進制字符串進行異或,這個很簡單,直接看代碼

在這裏插入圖片描述
用int函數將輸入的兩個16進制字符串轉爲整型
關於int函數的說明如下
在這裏插入圖片描述
然後進行異或,再將結果轉爲16進制
測試如下
在這裏插入圖片描述
直接返回函數的結果會看到結果前還有0x,所以需要使用[2:]進行截取
完整代碼及測試如下
在這裏插入圖片描述
打印出了異或的結果,用斷言測試如下
在這裏插入圖片描述

0x03
第三關
在這裏插入圖片描述
給定一個十六進制字符串hexString,它是某個字符串與一個單字符key異或進行加密之後得到的結果。現在已知hexString,我們需要找到key,來解密字符串。
這裏給了個提示,爲了驗證解密結果的正確,我們可以查看解密後的文本的字符頻率,來對解密結果進行評估。如果爲正常的英文文本,那麼它的字符頻率應該儘可能的大,選擇其中得分最高的key,即有很大概率爲正確的key
這個原理不難理解,出現頻率最高的是””(空格),第二高是’e’,如果一段文本,將其每個字符按照頻率表的數值相加,得分越高,則越有可能是正常的文本。
舉個不太恰當的例子(因爲頻率表是基於海量的正常文本得出的,而我這裏只是用簡單的一句話)。 比如一段密碼,解密後有兩個結果:
I am fine
A bc defg
第一個結果的分值應爲:0.06+0.07+0.02+0.02+0.06+0.06+0.10=0.39
第二個結果的分值應爲:0.07+0.01+0.02+0.03+0.10+0.02+0.02=0.18
則第一個結果應該纔是正確解密的結果。
接下來的代碼就是根據這個原理寫出來的。

字符頻率表
在這裏插入圖片描述
計算輸入文本的分值:該分值是所有在輸入字符串中出現的字符對應在字符頻率表中的頻率相加
在這裏插入圖片描述
對字符串中的每個字符與key進行異或
在這裏插入圖片描述
key_value是256個字符中的一個,暴力嘗試,用每個可能的字節對密碼異或解密,計算得出的明文的分數,得分越高,越可能是正確的密文,所用的key就是題目要求我們找出來的key
在這裏插入圖片描述
打印出解密後的明文,分數及key
在這裏插入圖片描述
完整的代碼及執行結果如下所示
在這裏插入圖片描述
成功解密了字符串
使用斷言測試如下
在這裏插入圖片描述

0x04
第四個題目
在這裏插入圖片描述
給了一個文件,該文件內容是和某個字符異或得到的,我們需要找到明文和key
文件內容如下
在這裏插入圖片描述
這裏在編碼時可以用到我們上個實驗寫過的函數,就不用重複造輪子了
在這裏插入圖片描述
對密文的每一個字符都進行暴力嘗試,與所有可能的key取值進行異或,最後組成明文,然後計算分數,返回分數最高的結果
在這裏插入圖片描述
完整代碼及運行結果如下所示
在這裏插入圖片描述
拿到了明文和key,使用斷言測試如下
在這裏插入圖片描述

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

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