彩虹表(rainbow table)

前記html

MD5的全稱是Message-Digest Algorithm 5(信息-摘要算法);算法

特色是不可逆的,通常解密不了;那有沒有想過,爲何各類工具網站均可以進行MD5解密呢?https://www.sojson.com/encrypt_md5.html數據庫

彩虹表,瞭解一下。編程

 

 

1. 如何存儲密碼纔是安全的?

密碼存儲有幾種方式:json

  • 直接存儲密碼明文m
  • 存儲密碼明文的哈希值hash(m)
  • 存儲密碼明文的加鹽哈希 hash(m+salt),這裏的salt能夠是用戶名,手機號等,但必須保證每一個用戶的salt都不同纔是安全的。

若是數據庫被入侵。
第一方式,明文存儲,無安全性可言。
第二種方式,雖然是入侵者獲得的是hash值,但因爲彩虹表的存在,也很容易批量還原出密碼明文來。
只有第三種方式纔是相對安全的。安全

2. 彩虹表不是 密碼-->明文 的簡單存儲

要從c=hash(m)逆向獲得原始明文m,有三種辦法:函數

  • 暴力破解法:時間成本過高。
  • 字典法:提早構建一個「明文->密文」對應關係的一個大型數據庫,破解時經過密文直接反查明文。但存儲一個這樣的數據庫,空間成本是驚人的。
  • 構建彩虹表:在字典法的基礎上改進,以時間換空間。是如今破解哈希經常使用的辦法。

3.  彩虹表的前身--預先計算的散列鏈

既然存儲全部的明文密碼對須要的空間太大,密碼學家們想出了一種以計算時間下降存儲空間的辦法:「預計算的哈希鏈集」(Precomputed hash chains)。
這是一條k=2哈希鏈:工具

 
哈希鏈


H函數就是要破解的哈希函數。
約簡函數(reduction function)R函數是構建這條鏈的時候定義的一個函數:它的值域和定義域與H函數相反。經過該函數能夠將哈希值約簡爲一個與原文相同格式的值。
這條鏈是這樣生成的:網站

 

  • 隨機選擇一個明文aaaaaa
  • 對其求哈希獲得281DAF40
  • R(281DAF40) 獲得另一個明文sgfnyd。
  • 繼續重複2,3步驟
    存儲的時候,不須要存儲全部的節點,只須要存儲每條鏈的頭尾節點(這裏是aaaaaa和kiebgt)

以大量的隨機明文做爲起節點,經過上述步驟計算出哈希鏈並將終節點進行儲存,可獲得一張哈希鏈集。加密

預計算的哈希鏈集的使用

要破解一個hash值,

  • 假設其恰好是920ECF10:首先對其進行一次R運算,獲得kiebgt,而後發現恰好命中了哈希鏈集中的(aaaaaa,kiebgt)鏈條。能夠肯定其極大機率在這個鏈條中。因而從aaaaaa開始重複哈希鏈的計算過程,發現sgfnyd的哈希結果恰好是920ECF10,因而破解成功。
  • 密文不是「920ECF10」而是「281DAF40」:第一次R運算後的結果並未在末節點中找到,則再重複一次H運算+R運算,這時又獲得了末節點中的值「kiebgt」。因而再從頭開始運算,可知aaaaaa恰好可哈希值爲281DAF40。
  • 如是重複了k(=2)次以後,仍然沒有在末節點中找到對應的值,則破解失敗。
預計算的哈希鏈集的意義

對於一個長度爲k的預計算的哈希鏈集,每次破解計算次數不超過k,所以比暴力破解大大節約時間。
每條鏈只保存起節點和末節點,儲存空間只需約1/k,於是大大節約了空間。

R函數的問題

要發揮預計算的哈希鏈集的左右,須要一個分佈均勻的R函數。當出現碰撞時,就會出現下面這種狀況
111 --H--> EDEDED --R--> 222 --H--> FEDEFE --R--> 333 --H--> FEFEDC --R--> 444
454 --H--> FEDECE --R--> 333 --H--> FEFEDC --R--> 444 -H--> FEGEDC --R--> 555

兩條鏈出現了重疊。這兩條哈希鏈能解密的明文數量就遠小於理論上的明文數2×k。因爲集合只保存鏈條的首末節點,所以這樣的重複鏈條並不能被迅速地發現。

4. 彩虹表

彩虹表的出現,針對性的解決了R函數致使的鏈重疊問題:
它在各步的運算中,並不使用統一的R函數,而是分別使用R1…Rk共k個不一樣的R函數(下劃線表示下標)。

 
彩虹表


這樣一來,及時發生碰撞,一般會是下面的狀況:
111 --H--> EDEDED --R1--> 222 --H--> FEDEFE --R2--> 333 --H--> FEFEDC --R3--> 444
454 --H--> FEDECE --R1--> 333 --H--> FEFEDC --R2--> 474 -H--> FERFDC --R3--> 909
即便在極端狀況下,兩個鏈條同一序列位置上發生碰撞,致使後續鏈條徹底一致,這樣的鏈條也會由於末節點相同而檢測出來,能夠丟棄其中一條而不浪費存儲空間。

 

4.1 彩虹表的使用

彩虹表的使用比哈希鏈集稍微麻煩一些。

  • 首先,假設要破解的密文位於某一鏈條的k-1位置處,對其進行Rk運算,看是否可以在末節點中找到對應的值。若是找到,則能夠如前所述,使用起節點驗證其正確性。
  • 不然,繼續假設密文位於k-2位置處,這時就須要進行Rk-一、H、Rk兩步運算,而後在末節點中查找結果。
  • 如是反覆,最不利條件下須要將密文進行完整的R一、H、…Rk運算後,才能得知密文是否存在於彩虹表之中。

4.2 彩虹表中時間、空間的平衡

對於哈希鏈集,最大計算次數爲k,平均計算次數爲k/2
彩虹表的最大計算次數爲1+2+3+……k = k(k-1)/2,平均計算次數爲[(k+2) * (k +1)]/6。
可見,要解相同個數的明文,彩虹表的代價會高於哈希鏈集。

不管哈希鏈集仍是彩虹表:
當k越大時,破解時間就越長,但彩虹表所佔用的空間就越小;
相反,k越小時,彩虹表自己就越大,相應的破解時間就越短。

4.3 常見的彩虹表和R函數舉例

1)常見的彩虹表:http://project-rainbowcrack.com/table.htm
2)R函數舉例:假設明文爲5位數字,則R函數是取哈希值中前5個數字。參見https://crypto.stackexchange.com/questions/5900/example-rainbow-table-generation

 

5. 彩虹表的獲取

能夠本身編程生成彩虹表,也可使用RainbowCrack或Cain等軟件來生成,有興趣的讀者能夠自行百度。彩虹表的生成時間與字符集的大小、哈希鏈的長度成正比,以下圖中「7位密碼、所有字符集、哈希鏈長度爲2萬」的彩虹表大小爲32G,本地生成大約須要332天,而從網上下載只須要2個小時左右,主流的彩虹表的大小廣泛在100G以上,想要本身生成是幾乎不可能的事,所以強烈建議黑客技術愛好者直接從網上下載。

彩虹表確實像它的名字同樣美好,至少黑客眼裏是這樣。上表是7位之內密碼在不一樣字符集下構造出的彩虹表的狀況,彩虹表中哈希鏈的長度和個數隨着字符集的增加而增加,彩虹表的大小和生成時間也隨之成倍增長。7位數字組合在彩虹表面前簡直就是秒破,即便最複雜的7位密碼不到一個小時就能破解,若是採用普通的暴力攻擊,破解時間可能須要三週。

6. 如何防護彩虹表

雖然彩虹表有着如此驚人的破解效率,但網站的安全人員仍然有辦法防護彩虹表。最有效的方法就是「加鹽」,即在密碼的特定位置插入特定的字符串,這個特定字符串就是「鹽」,加鹽後的密碼通過哈希加密獲得的哈希串與加鹽前的哈希串徹底不一樣,黑客用彩虹表獲得的密碼根本就不是真正的密碼。即便黑客知道了「鹽」的內容、加鹽的位置,還須要對H函數和R函數進行修改,彩虹表也須要從新生成,所以加鹽能大大增長利用彩虹表攻擊的難度。

7. 爲何加鹽哈希能夠抵禦彩虹表

彩虹表在生成的過程當中,針對的是特定的函數H,H若是發生了改變,則已有的彩虹表數據就徹底沒法使用。若是每一個用戶都用一個不一樣的鹽值,那麼每一個用戶的H函數都不一樣,則必需要爲每一個用戶都生成一個不一樣的彩虹表。大大提升了破解難度。

相關文章
相關標籤/搜索