【密碼學】彩虹表

        以前和很多人一樣,對彩虹表的理解是片面的:以爲彩虹表是一個大的“明文->密文”的映射表。按照這個理解(也就是暴力破解)某個哈希函數的彩虹表的容量是超大超大的,即使對明文做了分類。
        今天看了一下上面鏈接的那個帖子後,對彩虹表有了更確切的理解。彩虹表(Rainbow table)所謂的time-memory trade-off,並不是簡單地“以空間換時間”,而是雙向的“交易”,在二者之間達到平衡。
        首先我們簡單回憶下哈希函數的特性,一個輸入對應一個固定輸出,可能存在碰撞(多個輸入對應的哈希值相同),不可逆。

一、哈希鏈集

1.哈希鏈的原理

        在彩虹表之前,已經出現了對哈希函數的破解算法,被稱爲“預計算的哈希鏈集”(Precomputed hash chains)。當面對要破解的哈希函數H,首先要定義一個函數R,該函數的定義域和值域與哈希函數相反,通過該函數可以將哈希值映射爲一個與原文相同格式的值。需要強調的是,由於哈希函數是不可逆的,所以對於密文進行R運算幾乎不可能得到明文原文。

(1)構造一條哈希鏈

此處k=2

        H,R重複次數記爲k,k值應該適當,k太大容易出現重複子鏈,太小存儲空間太大。我們只存儲每條鏈的起點和終點,若干條哈希鏈構成哈希鏈集。

(2)使用哈希鏈破解密文

已知一個密文,假設是y:

(i)對密文進行R運算R(y),將R(y)在終點表中查詢;

        若查詢失敗,繼續進行H、R運算,查詢;最多進行K次R運算,要麼查詢成功,要麼破解失敗。

        若查詢成功,執行步驟(ii)

(ii)查明文並驗證

        由查詢匹配到的終點對應的起點,重複進行H、R運算:起點→my=H(m)→R(y)

        起點→my是查明文過程,y→R(y)是驗證過程。查到明文就是m。

(3)舉例

            y=D2A82C9A,R(y)=vfkkd,查表失敗;H(vfkkd)=0CAFC376,R(0CAFC376)=crepa,查表成功。

            相應起點終點分別是zhihu、crepa 。

            查明文並驗證:

            


        一條哈希鏈代表了k組明文密文對,但它只存儲起點終點,因此相對於暴力表大大節省了空間。哈希鏈破解最耗時的操作就是查詢終點,由於終點數(鏈數)遠遠小於密文數,因此相對於暴力表大大節省了時間。

2.R函數

R函數的選取要求:

(1)將值域限定在固定的範圍之內。事實上,在計算和下載彩虹表時,需要使用不同的庫的。按照不同的哈希函數、字符集、密碼長 等分爲很多個不同的庫。

(2)儘量保證R的值域均勻分佈,以減少碰撞。

然而實際上很難找到能滿足這些要求的完美的R函數。當計算中發生碰撞時,就會出現如下的子鏈重複的問題:


圖中加粗的部分,所涉及到的明文是完全重複的,因此這兩條哈希鏈能解密的明文數量就遠小於理論上的明文數2k。不幸的是,由於集合只保存鏈條的首末節點,因此這樣的重複鏈條並不能被迅速地發現。隨着碰撞的增加,這樣的重複鏈條會逐漸造成嚴重的冗餘和浪費。

二、彩虹表

1.彩虹表的構造

        爲了解決前面“子鏈重複”的問題,不再使用單一的R函數,而是使用不同的Ri函數(故稱爲彩虹表)。

此處k=3

        當兩鏈發生碰撞的位置不在同一位置時,後續的R函數的不一致使得鏈條的後續部分也不同,從而最大程度地減小了鏈條中的重複子鏈。同時,如果在極端情況下,兩個鏈條有1/k的概率在同一序列位置上發生碰撞,導致後續鏈條完全一致,這樣的鏈條也會因爲末節點相同而檢測出來,可以丟棄其中一條而不浪費存儲空間。

不同的彩虹表使用的R函數集不同。

2.使用彩虹表破解密文

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

已知一個密文,假設是y:

(i)假設密文在k-1位置,對密文進行Rk運算Rk(y),將Rk(y)在終點表中查詢;若查詢成功,執行步驟(ii),若查詢失敗,

        假設密文在k-2位置,對密文進行Rk-1、H,Rk運算,將結果Rk(H(Rk-1(y)))在終點表中查詢;若查詢成功,執行步驟(ii),若查詢失敗,

            假設密文在k-3位置,......

            假設密文在0位置,對密文進行反覆Ri,H運算,將結果在終點表中查詢;若查詢成功,執行步驟(ii),若查詢失敗,破解失敗。

(ii)查明文並驗證

        由查詢匹配到的終點對應的起點,重複進行H、R運算:起點→my=H(m)→Ri(y)

        起點→m→y是查明文過程,y→Ri(y)是驗證過程。查到明文就是m。


舉例:

y=85E4969A

假設密文在2位置:R3(y)查詢失敗;假設密文在1位置:R3(H(R2(y)))查詢失敗;

假設密文在0位置:R3(H(R2(H(R1(y)))))=biqkz查詢成功;

查明文並驗證:明文就是share

3.時空分析

        彩虹表減少了沒必要的重複子鏈,相對於哈希鏈集節省了空間;假設鏈長位2k+1(密文k個,明文K+1個),在最壞的情況下即破解失敗的情況下,哈希鏈集進行K次R運算,彩虹表進行1+2+3...+K=k(K+1)/2次R運算,所以彩虹表比哈希鏈集耗時更多。這就是時空的平衡。

三、防禦彩虹表攻擊

        關於彩虹表的防禦方法,與哈希函數H有關。

1.加鹽

        最常用的方法,就是加鹽(salt),實際上相當於改變了哈希函數H的形式。由於彩虹表在構造和破解的過程中,反覆用到了H,H如果發生了改變,則已有的彩虹表數據就完全無法使用,必須針對特定的H重新生成彩虹表,這樣就提高了破解的難度。

2.增加哈希函數H的複雜度

        防禦彩虹表的另一種方法是提高H函數的複雜度,例如將H定義爲計算一千次MD5後的結果。由於H在算法中的重複性,當單次H函數的計算耗時增加,意味着彩虹表的生成時間會大大的增加,從而也能提高破解的成本。

轉自:知乎Smallay

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