MD5算法破解思路

https://blog.csdn.net/wufaliang003/article/details/79794982
小明:老師,上次您講了MD5算法。用它生成的信息摘要,真的可以被破解嗎?

老師:有很多種方法可以破解,不過需要明確一點,這裏所謂的破解,並非把摘要還原成原文。爲什麼呢?因爲固定128位的摘要是有窮的,而原文數量是無窮的,每一個摘要都可以由若干個原文通過Hash得到。

小明:如果是這樣的話,網上所說的MD5破解到底是怎麼回事呢?

老師:對於MD5的破解,實際上都屬於【碰撞】。比如原文A通過MD5可以生成摘要M,我們並不需要把X還原成A,只需要找到原文B,生成同樣的摘要M即可。

設MD5的哈希函數是H(X),那麼:

H(A) = M

H(B) = M

任意一個B即爲破解結果。

B有可能等於A,也可能不等於A。

用一個形象的說法,A和B的MD5結果“殊途同歸”。

MD5碰撞通常用於登陸密碼的破解。應用系統的數據庫中存儲的用戶密碼通常都是原密碼的MD5哈希值,每當用戶登錄時,驗簽過程如下:
在這裏插入圖片描述

如果我們得到了用戶ABC的密碼哈希值E10ADC3949BA59ABBE56E057F20F883E,並不需要還原出原密碼123456,只需要“碰撞”出另一個原文654321(只是舉例)即可。登錄時,完全可以使用654321作爲登陸密碼,欺騙過應用系統的驗籤。
在這裏插入圖片描述

小明:那麼,具體如何來實現MD5摘要的碰撞呢?

老師:MD5碰撞的方法有很多,主要包括暴力枚舉法、字典法、彩虹表法等等。

暴力枚舉法:

老師:暴力枚舉法顧名思義,就是簡單粗暴地枚舉出所有原文,並計算出它們的哈希值,看看哪個哈希值和給定的信息摘要一致。這種方法雖然簡單,但是時間複雜度極高。想象一下,僅僅長度8位的密碼就有多少種排列組合的可能性?

小明:只考慮大小寫字母和數字,每一位有62種可能,那麼8位密碼的排列組合就是62的8次方,218340105584800,約等於二百萬億!

老師:是的,這樣的數據量如果使用普通的單機來破解,恐怕頭髮白了也破解不完。不過,我們也可以做一些取巧,優先嚐試生日和有意義的單詞,這樣就可以把窮舉範圍縮小很多。

字典法:

老師:如果說暴力枚舉法是ongoing時間換空間,那麼字典法則是用空間換時間。黑客利用一個巨大的字典,存儲儘可能多的原文和對應的哈希值。每次用給定的信息摘要查找字典,即可快速找到碰撞的結果。
在這裏插入圖片描述

不過,這樣做雖然每次破解速度很快,但是生成字典需要巨大的空間。仍然以8位密碼舉例,需要多大空間呢?

小明:剛纔計算過有218340105584800種可能性,每一對映射佔192(128+64)bit。那麼大約需要4.65PB的存儲空間。

老師:沒錯,這樣做的存儲成本實在太大了。當然,我們同樣可以取巧,優先存儲那些常用的密碼及其摘要。

小明:那麼,有沒有什麼方法可以做到時間和空間的均衡呢?

老師:有一種方法可以,那就是下面我要介紹的【彩虹表發】。

彩虹表法:

老師:彩虹表法可以說是對字典法的優化,它採用了一種有趣的數據結構:【彩虹表】。在學習彩虹表之前,我們先來了解兩個基本函數:H(X)和R(X)。

H(X):生成信息摘要的哈希函數,比如MD5,比如SHA256。

R(X):從信息摘要轉換成另一個字符串的衰減函數(Reduce)。其中R(X)的定義域是H(X)的值域,R(X)的值域是H(X)的定義域。但要注意的是,R(X)並非H(X)的反函數。

通過交替運算H和R若干次,可以形成一個原文和哈希值的鏈條。假設原文是aaaaaa,哈希值長度32bit,那麼哈希鏈表就是下面的樣子:
在這裏插入圖片描述

這個鏈條有多長呢?假設H(X)和R(X)的交替重複K次,那麼鏈條長度就是2K+1。同時,我們只需把鏈表的首段和末端存入哈希表中:

在這裏插入圖片描述

小明:這什麼跟什麼啊,衰減函數和哈希鏈條,到底是幹什麼用的?

老師:別急,我們來演示一次破解過程,你就明白它們的意義了。

給定信息摘要:920ECF10

如何得到原文呢?只需進行R(X)運算:

R(920ECF10)= kiebgt

查詢哈希表可以找到末端kiebgt對應的首端是aaaaaa,因此摘要920ECF10的原文“極有可能”在aaaaaa到kiebgt的這個鏈條當中。

接下來從aaaaaa開始,重新交替運算R(X)與H(X),看一看摘要值920ECF10是否是其中一次H(X)的結果。從鏈條看來,答案是肯定的,因此920ECF10的原文就是920ECF10的前置節點sgfnyd。
在這裏插入圖片描述
在這裏插入圖片描述

需要補充的是,如果給定的摘要值經過一次R(X)運算,結果在哈希表中找不到,可以繼續交替H(X)R(X)直到第K次爲止。

簡單來說,哈希鏈表代表了一組映射關係,其中每組包含K對映射,但只需要存儲鏈條首位兩個字符串。假設K=10,那麼存儲空間只有全量字典的十分之一,代價則是破解一個摘要的運算次數也提高了十倍。這就是時間和空間的取捨。雖然做了取捨,但是哈希鏈條存在一個致命的缺陷:R(X)函數的可靠性。雖然我們儘量把R(X)設計成結果均勻分佈的函數,但是再完美的函數也難免會有碰撞的情況,比如下面這樣:

給定信息摘要:FB107E70

經過多次R(X),H(X)運算,得到結果kiebgt

通過哈希表查找末端kiebgt,可以找出首端aaaaaa

但是,FB107E70並不在aaaaaa到kiebgt的哈希鏈條當中,這就是R(X)的碰撞造成的。
在這裏插入圖片描述

這個問題看似沒什麼影響,既然找不到就重新生成一組首尾映射即可。但是想象一下,當K值較大的時候,哈希鏈很長,一旦兩條不同的哈希鏈在某個節點出現碰撞,後面所有的明文和哈希值全都變成了一毛一樣的值。

這樣造成的後果就是冗餘存儲。原本兩條哈希鏈可以存儲 2K個映射,由於重複,真正存儲的映射數量不足2K。

這個時候,我們設計了彩虹表。彩虹表對哈希鏈進行了改進,把原先的R(X)的函數改進成從R1(X)到Rk(X)一共K個衰減函數。這樣一來雖然也可能發生碰撞,但是碰撞只會發生在同一級運算,如R1和R1碰撞,R3和R3碰撞,大大減小了存儲重複的機率。
在這裏插入圖片描述

小明:好複雜,聽的頭都暈了。那想要破解MD5算法,有沒有比彩虹表更厲害的方法呢?

老師:還真有。

2004年,王小云教授提出了非常高效的MD5碰撞方法。

2009年,馮登國、謝濤利用差分攻擊,將MD5的碰撞算法複雜度進一步降低。

有興趣的小夥伴可以通過資料進行更深入的學習。

幾點補充:

對於單機來說,暴力枚舉法的時間成本很高,字典法的空間成本很高。但是利用分佈式計算和分佈式存儲,仍然可以有效破解MD5算法。因此這兩種方法同樣被黑客們廣泛使用。
————————————————
版權聲明:本文爲CSDN博主「HelloWorld搬運工」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/wufaliang003/article/details/79794982

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