現在是晚上23:29。寫這篇文章呢,是因為早些時候我胃疼,是因為涼導致的胃疼。涼呢喝了一些熱水,喝完熱水胃倒是不疼了,但是由於我喝的是茶葉開水,於是就導致失眠了。想來想去這漫漫長夜也沒意思,於是就決定寫這個了。
0X01
這個md5碰撞到底是個什么東西呢,這是王小雲發明的一種破解md5摘要算法的的一種方法。這個md5密文,有16位的md5以及32位的md5,然而,32位的md5密文和16位的md5密文它們的區別就是長度不一樣,其他沒有什么技術上的區別。將同一個字符串加密為16位md5密文和32位md5密文,在32位的md5中減去前8位和后8位,中間的部分就是它的16位md5。例如將字符串admin加密,admin的16位md5是7a57a5a743894a0e,32位md5是21232f297a57a5a743894a0e4a801fc3,去掉32位的前8位和后8位,你看它中間剩下的是不是就是16位md5了。md5密文是由字母和數字組成的,但是md5不區分大小寫,也就是由26個字母和10個數字組成的16位的字符串。所以md5密文的總個數一共就是36的16次方個,也就是全宇宙的md5密文總共有1208925819614600000000000個,雖然這是一個很大的數,但是它終究是有限制的,它就只有這么多個,沒有辦法再+1了,再多一個就重復了,然而明文呢,卻是無限制的,不限長度的有標點、大小寫字母以及數字組成的字符串有無數個,這是沒有辦法估量,因為不限長度。然而這無限種明文卻都可以用16位的md5表示出來,要用有限數量的東西去表示另一種無限數量的東西,就勢必會存在重復,這就是碰撞。由於數量太大,就用數字來代替舉例,例如0~9就是md5密文(有限個數),26個字母就是明文(明文數量遠大於密文數量),用0表示a,1表示b,2表示c,最多只能表示10個字母。10個數字表示完前10個字母,然而又必須用10個數字表示完26個字母,那么就只能重復了,這是唯一的解決辦法了,9表示的字母是i,i后面的字母是j,那這個j就必須要用已經用過的數字來表示了,這樣的話從字母j開始,1個數字最少都要表示2個字母了,這就存在碰撞了。j就又要用0來表示。所以簡單來說,碰撞算法就是找到另外一個加密以后md5值與原字符串相同的新字符串。碰撞算法會產生多少個結果呢,這是無法估計的,原因也是因為無法限制明文的長度是多少,假如說100位長度的時候就碰撞出md5值與admin相同的字符串,那長度是1000位呢,是100000呢,會碰撞出多少個字符串?這無法計算。如果限制了長度,萬一碰撞不出來呢?就要調大長度了。
0X02
碰撞破解對安全的實質性影響?碰撞算法是一種能夠100%破解掉md5的一種破解算法(就像窮舉一樣)。就用網頁登陸做為例子,假如存在一個賬號:root,它的密碼是:a,然后網頁向數據庫查詢賬號root的密碼的md5是多少,然后再對比輸入的密碼,如果輸入的密碼的md5與查詢到的md5是一樣的,那就說明賬號和密碼輸入正確,允許登陸,否則賬號密碼錯誤。假如說a的md5是0,然后碰撞出j的md5密文也是0,那輸入賬號root和密碼j會發生什么情況,肯定是允許登陸,因為原密碼a的md5是0,而j的md5也是0,輸入的密碼的md5和數據庫中查詢到的密碼md5是一樣的,那就說明密碼正確了,然后j並不是原始密碼,而是碰撞出的密碼。這就是碰撞破解。
0X03
理論上最多加密32的16次方+1次,就一定能碰撞出一個字符串的md5值跟某個字符串的md5相同,因為32的16次方就用完了所有的md5密文,因為md5密文的總個數就只有這么多個。再多1個字符串,就一定會出現兩個字符串的md5值完全相同的情況了。這32的16次方對於個人電腦來說是不可能的,然而能夠使用超級計算機的話,是100%能解md5的,如果你能夠搜集到32的16次方個不同的md5密文所對應的明文,那么你就100%能夠破解任何一個md5了。
0X04
碰撞破解並不是還原,md5是一種不可逆的加密,也就是說它本身就是無法還原的
0X05
crc32碰撞。crc32碰撞的概率相當高,這個我之前並不了解,是我在工作中偶然發現的,當時我還以為我發現了新大陸,結果谷歌一搜,早就有人發現了。這就是crc32碰撞。事件的起因是這樣的,前段時間我用Python寫了一個破解zip壓縮包密碼的程序,這個程序我已經開源,放在博客上可以任意下載免費使用,地址是www.tech-era.top/file/hackzip.zip。破解的原理是窮舉,然后程序寫好以后呢就要測試,於是我壓縮了一個空白文本文檔,我將壓縮包的密碼設置為56(設置為56是亂按的),密碼設置為數字組成的兩位數密碼,是因為這只有10的2次方個,也就是字典中的密碼只有100個,可以很快就窮舉完。當窮舉到56程序提示找到密碼了,說明我寫的這個程序是可以正常的工作的吧,然后我使用了另外一個字典,另外一個字典中並沒有正確密碼,這樣做是因為我想要測試當字典中沒有正確密碼的時候程序會不會按照設計那樣正常運行,然后使用這個我以為沒有正確密碼的字典時,程序仍然說找到了正確密碼,當時我並不知道是為什么,明明字典中就沒有正確密碼,我還以為是有bug,但是我連這個詭異的bug是怎么出現的都不知道,因為不應該出現這個bug,然后我就用解壓軟件解壓縮測試用的壓縮包,當用設置的56做解壓密碼時成功解壓縮了,然后我又用程序窮舉出的另一個密碼:612,還是成功解壓縮了,然后我又用另外一個字典對壓縮包進行窮舉,發現1251也可以作為密碼成功解壓縮。然后后來又進行了各種各樣的測試發現tm也可以作為密碼,所以說這個crc32碰撞的概率很高啊,在10000次的范圍內就碰撞出了兩個密碼(612和1251),當然,測試的前提條件是壓縮包的內容的一個空白文本文檔。但是壓縮包是其他內容時,肯定也是存在碰撞的。