1.1?哈希算法
1.1.1?Hash的定義
hash (哈希或散列)算法是IT領域非常基礎也非常重要的一類算法。可以將任意長度的二進制值(明文)映射為較短的固定長度的二進制值(Hash 值),并且不同的明文很難映射為相同的 Hash 值。hash 值在應用中又被稱為數字指紋(fingerprint)或數字摘要(digest)、消息摘要。
例如計算一段話“hello blockchain”的 MD5 hash 值為:78e6a8bcdef7a4a254c16054b082c783
這意味著只要對某文件進行 MD5 Hash 計算,得到結果為 78e6a8bcdef7a4a254c16054b082c783,這就說明文件內容極大概率上就是 “hello blockchain”。可見,Hash 的核心思想十分類似于基于內容的編址或命名。
一個優秀的 hash 算法,在給定明文和 hash 算法的情況下,可以在有限時間和有限資源內能計算出 hash 值。在給定(若干) hash 值的情況下,很難(基本不可能)在有限時間內逆推出明文。即使修改一點點原始輸入信息,也能對hash值產生巨大的改變。不同的輸入信息幾乎不可能產生相同的hash值。
1.1.2?流行的哈希算法
目前常見的?Hash 算法包括 Message Digest(MD)系列和 Secure Hash?Algorithm(SHA)系列算法。
MD 算法主要包括 MD4 和 MD5 兩個算法。MD4(RFC 1320)是 MIT 的 Ronald L. Rivest在?1990 年設計的,其輸出為 128 位。MD4 已證明不夠安全。MD5(RFC 1321)是 Rivest于?1991 年對 MD4 的改進版本。它對輸入仍以 512 位進行分組,其輸出是 128 位。MD5 比MD4 更加安全,但過程更加復雜,計算速度要慢一點。MD5 已于 2004 年被成功碰撞,其安全性已不足應用于商業場景。
SHA 算法由美國國家標準與技術院(National Institute of Standards and Technology,NIST)征集制定。首個實現 SHA-0 算法于 1993 年問世,1998 年即遭破解。隨后的修訂版本?SHA-1 算法在 1995 年面世,它的輸出為長度 160 位的 Hash 值,安全性更好。SHA-1 設計采用了?MD4 算法類似原理。SHA-1 已于 2005 年被成功碰撞,意味著無法滿足商用需求。為了提高安全性,NIST 后來制定出更安全的 SHA-224、SHA-256、SHA-384,和 SHA-512算法(統稱為?SHA-2 算法)。新一代的 SHA-3 相關算法也正在研究中。
目前認為 MD5 和 SHA1 已經不夠安全,推薦至少使用 SHA-256 算法。比特幣系統中就是使用SHA-256哈希算法。
SHA-3算法,之前被命名為Keccak算法。Keccak的輸出長度分別有:512、384、256、224
SHA-3并不是要取代SHA-2,因為SHA-2目前并沒有出現明顯的弱點。由于對MD5出現成功的破解,以及對SHA-1出現理論上破解的方法,NIST感覺需要一個與之前算法不同的、可替換的加密雜湊算法,也就是現在的SHA-3。區塊鏈中的以太坊系統就是使用Keccak256算法。
下面列舉數字1經過hash算法后形成的密文。
md5('1'),加密后長度為128位,16字節 。密文如下所示。??????????????????
c4ca4238a0b923820dcc509a6f75849b??//32位16進制數字
SHA1('1'),加密后長度為160位,20字節。密文如下所示。
356a192b7913b04c54574d18c28d46e6395428ab?????//40位16進制數字
RIPEMD-160('1'),加密后長度為160位,20字節。密文如下所示。?????????????????
c47907abd2a80492ca9388b05c0e382518ff3960??//40位16進制數字
SHA256('1'),加密后長度為256位,32字節。密文如下所示。
6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b //64位16進制數
Keccak256('1'),加密后長度為256位,32字節。密文如下所示。
c89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6 //64位16進制數
1.1.3?Hash與加密解密的區別
Hash是將目標文本轉換成具有相同長度的、不可逆的雜湊字符串,而加密(Encrypt)是將目標文本轉換成具有不同長度的、可逆的密文。如圖13.1所示。
圖1.1?哈希與加密
選擇哈希(Hash)與加密(Encrypt)的基本原則有如下兩點。
l?如果被保護數據僅僅用作比較驗證,在以后不需要還原成明文形式,則使用哈希;
l?如果被保護數據在以后需要被還原成明文,則需要使用加密。
對簡單哈希(Hash)的攻擊,主要有尋找碰撞法和窮舉法。
1. 尋找碰撞法
目前對于MD5和SHA1并不存在有效地尋找碰撞方法。
我國杰出的數學家王小云教授曾經在國際密碼學會議上發布了對于MD5和SHA1的碰撞尋找改進算法,但這種方法和“破解”相去甚遠。該理論目前僅具有數學上的意義,她將破解MD5的預期步驟降低了好幾個數量級,但對于實際應用來說仍然是一個天文數字。
2. 窮舉法(或暴力破解法)
通俗來說,就是在一個范圍內,如從000000到999999,將其中所有值一個一個用哈希算法哈希,然后將結果和雜湊串比較,如果相同,則這個值就一定是源字串或源字串的一個碰撞,于是就可以用這個值非法登錄了。
窮舉法看似笨拙,但目前幾乎所有的MD5破解機或MD5在線破解都是用這種窮舉法。糾其緣由,就是相當一部分口令是非常簡單的,如“123456”或“000000”。窮舉法是否能成功很大程度上取決于口令的復雜性。因為窮舉法掃描的區間往往是單字符集、規則的區間,或者由字典數據進行組合,因此,如果使用復雜的口令,例如“!@#$%^&*()”這種口令,窮舉法就很難奏效了。
1.1.4?SHA256
SHA-256算法輸入報文的最大長度不超過2^64 bit,產生的輸出是一個256-bit的報文摘要。SHA256算法步驟如下。
(1)step1:附加填充比特。
對報文進行填充使報文長度與448 模512 同余(長度=448 mod 512),填充的比特數范圍是1 到512,填充比特串的最高位為1,其余位為0。就是先在報文后面加一個 1,再加很多個0,直到長度滿足mod 512=448.為什么是448,因為448+64=512. 第二步會加上一個 64bit的原始報文的 長度信息。
(2)step2:附加長度值。
?將用64-bit 表示的初始報文(填充前)的位長度附加在步驟1的結果 后(低位字節優先)。
(3)step3:初始化緩存。
使用一個256-bit 的緩存來存放該散列函數的中間及最終結果。該緩存表示為A=0x6A09E667 , B=0xBB67AE85 , C=0x3C6EF372 , D=0xA54FF53A, E=0x510E527F , F=0x9B05688C , G=0x1F83D9AB , H=0x5BE0CD19 。
(4)step4:處理512-bit(16 個字)報文分組序列。
?該算法使用了六種基本邏輯函數,由64 步迭代運算組成。每步都以256-bit 緩存值ABCDEFGH 為輸入,然后更新緩存內容。