散列函數的應用及其安全性
散列函數的應用及其安全性
一、散列函數的具體應用
Hash(散列函數),一般翻譯做"散列",也有直接音譯為"哈希"的,就是把任意長度的輸入(又叫做預映射, pre-image),通過散列算法,變換成固定長度的輸出,該輸出就是散列值。這種轉換是一種壓縮映射,也就是,散列值的空間通常遠小於輸入的空間,不同的輸入可能會散列成相同的輸出,而不可能從散列值來唯一的確定輸入值。簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數。
由於散列函數的應用的多樣性,它們經常是專為某一應用而設計的。例如,加密散列函數假設存在一個要找到具有相同散列值的原始輸入的敵人,一個設計優秀的加密散列函數是一個“單向”操作:對於給定的散列值,沒有實用的方法可以計算出一個原始輸入,也就是說很難偽造。為加密散列為目的設計的函數,如MD5,被廣泛的用作檢驗散列函數,這樣軟件下載的時候,就會對照驗證代碼之後才下載正確的文件部分,此代碼有可能因為環境因素的變化,如機器配置或者IP地址的改變而有變動,以保證源文件的安全性。錯誤監測和修復函數主要用於辨別數據被隨機的過程所擾亂的事例,當散列函數被用於校驗和的時候,可以用相對較短的散列值來驗證任意長度的數據是否被更改過。
總體來說,散列函數的具體應用主要有以下三個方面:
1.錯誤校正
使用一個散列函數可以很直觀的檢測出數據在傳輸時發生的錯誤。在數據的發送方,對將要發送的數據應用散列函數,並將計算的結果同原始數據一同發送。在數據的接收方,同樣的散列函數被再一次應用到接收到的數據上,如果兩次散列函數計算出來的結果不一致,那麽就說明數據在傳輸的過程中某些地方有錯誤了。這就叫做冗余校驗。
對於錯誤校正,假設相似擾動的分布接近最小(a distribution of likely perturbations is assumed at least approximately)。對於一個信息串的微擾可以被分為兩類,大的(不可能的)錯誤和小的(可能的)錯誤。我們對於第二類錯誤重新定義如下,假如給定 H(x) 和 x+s,那麽只要s足夠小,我們就能有效的計算出x。那樣的散列函數被稱作錯誤校正編碼。這些錯誤校正編碼有兩個重要的分類:循環冗余校驗和裏德所羅門碼。
2.語音識別
對於像從一個已知列表中匹配一個MP3文件這樣的應用,一種可能的方案是使用傳統的散列函數——例如MD5,但是這種方案會對時間平移、CD讀取錯誤、不同的音頻壓縮算法或者音量調整的實現機制等情況非常敏感。使用一些類似於MD5的方法有利於迅速找到那些嚴格相同(從音頻文件的二進制數據來看)的音頻文件,但是要找到全部相同(從音頻文件的內容來看)的音頻文件就需要使用其他更高級的算法了。
那些並不緊隨IT工業潮流的人往往能反其道而行之,對於那些微小差異足夠魯棒的散列函數確實存在。現存的絕大多數散列算法都是不夠魯棒的,但是有少數散列算法能夠達到辨別從嘈雜房間裏的揚聲器裏播放出來的音樂的魯棒性。有一個實際的例子是Shazam服務,用戶可以用電話機撥打一個特定的號碼,並將電話機的話筒靠近用於播放音樂的揚聲器,該項服務會分析正在播放的音樂,並將它於存儲在數據庫中的已知的散列值進行比較,用戶就能夠收到被識別的音樂的曲名。
3.信息安全
Hash算法在信息安全方面的應用主要體現在以下的3個方面:
(1)文件校驗
我們比較熟悉的校驗算法有奇偶校驗和CRC校驗,這2種校驗並沒有抗數據篡改的能力,它們一定程度上能檢測並糾正數據傳輸中的信道誤碼,但卻不能防止對數據的惡意破壞。
MD5 Hash算法的"數字指紋"特性,使它成為目前應用最廣泛的一種文件完整性校驗和(Checksum)算法,不少Unix系統有提供計算md5 checksum的命令。
(2)數字簽名
Hash 算法也是現代密碼體系中的一個重要組成部分。由於非對稱算法的運算速度較慢,所以在數字簽名協議中,單向散列函數扮演了一個重要的角色。對 Hash 值,又稱"數字摘要"進行數字簽名,在統計上可以認為與對文件本身進行數字簽名是等效的。而且這樣的協議還有其他的優點。
(3)鑒權協議
如下的鑒權協議又被稱作挑戰--認證模式:在傳輸信道是可被偵聽,但不可被篡改的情況下,這是一種簡單而安全的方法。
二、散列函數的安全性以及目前安全散列函數的發展
1.散列函數的安全性
單向散列函數或者安全散列函數的重要性,不僅在於消息認證(消息摘要,數據指紋),還有數字簽名(加強版的消息認證)和驗證數據的完整性。常見的單向散列函數有MD5和SHA。
散列函數的目的是文件、消息或者其他數據塊產生“指紋”。為滿足在消息認證中的應用,散列函數H必須具有下列性質:
(1)H可適用於任意長度的數據塊。
(2)H能夠生成固定長度的輸出。
(3)對於任意給定的x,計算H(x)相對容易,並且可以用軟/硬件實現。
(4)對於任意給定的h,找到滿足H(x)=h的x在計算上不可行,滿足這一特性的散列函數稱之為:具備抗原像攻擊性。
(5)對於任意給定的數據塊x,找到滿足H(y)=H(x)的y ≠ x在計算上是不可行;滿足這一特性的散列函數稱之為:抗弱碰撞性。
(6)找到滿足H(x) = H(y)的任意一對(x,y)在計算上是不可行的。滿足這一特性的散列函數稱之為:抗碰撞性。
前三個性質是使用散列函數進行消息認證的實際可行要求。第四個屬性,抗原像攻擊,防止攻擊者能夠回復秘密值。抗弱碰撞性保證了對於給定的消息,不可能找到具有相同散列值的可替換消息。滿足上面前5個性質的散列函數稱之為弱散列函數。如果還滿足第6個性質則稱之為強散列函數。
Hash函數的安全性很大程度上取決於抗強碰撞的能力。目前已有的對Hash函數攻擊的方法包括生日攻擊、彩虹表攻擊、差分攻擊等。Hash函數的算法結構特點和Hash值的長度是決定函數碰撞性的而主要因素,Hash值越長,抵禦越強。SHA-256有256比特Hash值,MD5和SHA-1分別有128和160比特的Hash值。
到目前為止,有兩種方法可以攻擊安全散列函數:密碼分析法和暴力攻擊法。散列函數抵抗暴力攻擊的強度完全依賴於算法生成的散列碼長度。
Van Oorschot和Wiener曾經提出,花費1000萬美元涉及一個被專門用來搜索MD5算法碰撞的機器,則平均24天內就可以找到一個碰撞。2004年8月中國密碼學家王小雲教授等首次公布了提出一種尋找MD5碰撞的新方法。目前利用該方法用普通微機幾分鐘內即可找到MD5的碰撞。MD5已經唄徹底攻破。
2.目前安全散列函數的發展
1997年Bob Jenkins 在Dr. Dobbs 的期刊上發表了一篇關於hash函數的文章:A hash function for hash Table lookup。在這篇文章中,Bob廣泛的歸類了已存的hash函數,並提出了自己的”lookup2”。隨後他又在2006年發布了lookup3 ,可以說這是第一個“現代”的hash函數,從某種意義上來說它不僅快速(0.5bytyes/cycle according to Bob)而且沒有任何嚴重缺陷。
2008年Austin Appleby 發表了一個新的稱作“MurmurHash”的hash 函數。在它最近的版本中其hash速度大約是lookup3的2倍(大約1byte/cycle),並且同時有32-bit和64-bit兩個版本。32-bit版的只使用32-bit公式並輸出32-bit的hash,64-bit版的使用64-bit公式產出64-bit的hash。跟據Austin的分析該函數擁有優秀的特性,然而Bob Jenkins在DR.Dobbs上發表的擴充文章說:我能看到[MurmurHash]比我的lookup3差,但是我不知道差多少,我沒有測試。由於優秀的速度和統計特性,MurmurHash很快就變的流行起來。
2011年兩個基於MurmurHash的改進函數發表,這兩個函數都是在指令級別的並行性上對MurmurHash進行了加強。Google發布了CityHash(written by Geoff Pike and Jyrki Alakuijala),Bob Jenkins 發布了自己的SpookyHash。兩個函數都是原MurmurHash速度的2x,但兩個函數都使用了64-bit的公式,而沒有32-bit的版本。CityHash依賴於CRC32指令集,該指令出現在SSE 4.2(Intel Nehalem及以後)。SpookyHash產生128位的輸出,而CityHash有64-bit,128-bit和256-bit可選。
MD5 和 SHA1 是目前應用最廣泛的Hash算法,而它們都是以 MD4 為基礎設計的。MD4(RFC 1320)是 MIT 的Ronald L. Rivest在 1990 年設計的,MD 是 Message Digest 的縮寫。它適用在32位字長的處理器上用高速軟件實現--它是基於 32位操作數的位操作來實現的。
MD5(RFC 1321)是 Rivest 於1991年對MD4的改進版本。它對輸入仍以512位分組,其輸出是4個32位字的級聯,與 MD4 相同。MD5比MD4來得復雜,並且速度較之要慢一點,但更安全,在抗分析和抗差分方面表現更好。
SHA1是由NIST NSA設計為同DSA一起使用的,它對長度小於2^64位的輸入,產生長度為160bit的散列值,因此抗窮舉(brute-force)性更好。SHA-1 設計時基於和MD4相同原理,並且模仿了該算法。
三、使用md5算法來驗證軟件完整性時可能出現的問題
MD5即Message-Digest Algorithm 5(信息-摘要算法5),用於確保信息傳輸完整一致。是計算機廣泛使用的雜湊算法之一(又譯摘要算法、哈希算法),主流編程語言普遍已有MD5實現。將數據(如漢字)運算為另一固定長度值,是雜湊算法的基礎原理,MD5的前身有MD2、MD3和MD4。
MD5算法的作用是讓大容量信息在用數字簽名軟件簽署私人密鑰前被"壓縮"成一種保密的格式(就是把一個任意長度的字節串變換成一定長的十六進制數字串)。除了MD5以外,其中比較有名的還有sha-1、RIPEMD以及Haval等。
MD5算法具有以下特點:
1、壓縮性:任意長度的數據,算出的MD5值長度都是固定的。
2、容易計算:從原數據計算出MD5值很容易。
3、抗修改性:對原數據進行任何改動,哪怕只修改1個字節,所得到的MD5值都有很大區別。
4、強抗碰撞:已知原數據和其MD5值,想找到一個具有相同MD5值的數據(即偽造數據)是非常困難的。
MD5算法可以被用來驗證文件的完整性和是否被篡改,通過對任意長度的信息逐位進行計算,產生一個二進制長度為128位(十六進制長度就是32位)的 hash 值, 不同的文件產生相同的hash的可能性是非常小的。MD5在實際應用中通常有兩種用法,一種是計算一個字符串的MD5值,常用於密碼相關的操作;另一種是用於計算一個文件的MD5值,一般用於網絡傳輸中驗證文件是否出錯。具體應用體現在以下三個方面:
1、一致性驗證
MD5的典型應用是對一段文本信息產生信息摘要,以防止被篡改。常常在某些軟件下載站點的某軟件信息中看到其MD5值,它的作用就在於我們可以在下載該軟件後,對下載回來的文件用專門的軟件(如Windows MD5 Check等)做一次MD5校驗,以確保我們獲得的文件與該站點提供的文件為同一文件。
2、數字證書
如果有一個第三方的認證機構,用MD5還可以防止文件作者的“抵賴”,這就是所謂的數字簽名應用。
3、安全訪問認證
在Unix系統中用戶的密碼是以MD5(或其它類似的算法)經Hash運算後存儲在文件系統中。當用戶登錄的時候,系統把用戶輸入的密碼進行MD5 Hash運算,然後再去和保存在文件系統中的MD5值進行比較,進而確定輸入的密碼是否正確。通過這樣的步驟,系統在並不知道用戶密碼的明碼的情況下就可以確定用戶登錄系統的合法性。
但是,在使用MD5算法來驗證完整性時,由於MD5算法是公開的,所有人都可以獲得和使用MD5算法,那就意味著別人可以利用相同的算法針對你的加密值不斷地進行計算。如果不對MD5算法進行一些處理,那麽當我們將自己的重要接口暴露在互聯網上的時候,比如登陸接口,攻擊者就可以同樣利用MD5加密算法對我們進行撞庫攻擊和關鍵信息比對。為了避免這個問題,我們可以給算法增加一個偏移量,比如在原始數據上拼接一段數據在進行加密;或者根據原始數據分布範圍進行轉換,用得到的新值進行MD5計算,這樣子被破解的風險就會大大降低。
散列函數的應用及其安全性