Haorui: 先舉個例子吧。假如有一天老闆要你在裝置上測試某一個軟體版本。于是你就開始從美國的伺服器上下載下傳這個軟體版本。下載下傳的時候才發現軟體非常大,有好幾個G,網速又很慢。這個下去,搞不好要下三天兩夜呢。這時候,Michael哥過來說,Lauren,我裡有這個軟體版本,前幾天下的,你拷過去好了。
Lauren: 挺好,我就用Michael哥的。
Haorui: 慢着,這裡有一個問題,Michael哥給你的軟體會不會有問題呢?比如Michael在軟體裡面植入一個病毒。一旦你使用這個帶病毒的軟體,它就會自動聯網,把裝置上的資料全部發出去。
Lauren: 啊!有這麼嚴重嗎?Michael哥是好人,他不會這麼幹的。
Haorui: OK,也許你說的是對的。但是要注意哦,相對于機器而言,人是不可靠的。還有一種可能,Henry在昨天攻擊了Michael的電腦,在Michael不知情的情況下,植入一個軟體木馬到你要的版本上。一旦帶木馬的軟體版本被執行,你的裝置就被攻擊者遠端控制了。
Lauren: 啊!Michael哥的軟體不能用呀,從伺服器上下載下傳又很慢。這個怎麼辦呢?不行,Henry也是好人,他也不會幹壞事的。
Haorui: OK, 攻擊者可以不是Henry,也許是Bjorn,Tony。總之世上總有壞人,你說對吧。
Lauren: 哪怎麼辦呢?我總感覺你在忽悠我,你說的都是非常小的機率事件。Michael的軟體99.99%是原版的。關鍵是……
Haorui: 關鍵是什麼?
Lauren: 關鍵是我要找一種方式來驗證Michael哥的軟體是否可靠。
Haorui: You got it。問題的關鍵是你要有一種方式驗證Michael哥的軟體是原版的。前面我們學習的對稱與非對稱密碼系統,可以解決資訊的機密性。而今天我們要讨論的是消息的完整性,及消息沒有被惡意篡改。這是一個重要的安全問題。有什麼技術手段可以做到呢?
Lauren: 我想到一種辦法,用CRC校驗。每次在伺服器上放軟體的時候,同時計算一個CRC值放在一起。現在我計算一下Michael哥軟體的CRC值,再與伺服器是的CRC值比一下,如果是一緻的,說明Michael哥的軟體是沒有問題的。見圖7.1我設計的流程圖。
Haorui: 看起來不錯,你的方案從流程上可以實作。但是Michael可能比你想像的更聰明。Michael在植入病毒的時候,考慮了這個問題,他會對病毒作一些修改,調整,使整個軟體的CRC值與伺服器上的CRC值一樣。這樣你就沒有辦法了。
Lauren: 看來用CRC不行,應該設計一個算法,讓Michael哥哪怕改了一個比特位我們都可以發現。
Haorui: 這個就是今天要講的哈希函數,或者說單向散列函數。通過它計算出來的值叫哈希值或者叫消息的摘要,或是消息的指紋。看看專業的流程如下, 圖7.2.
把CRC替換成Hash函數就可以了。首先在你的本地計算Michael哥的軟體的Hash值,然後與伺服器上的對比。就可以确定軟體的完整性。Hash值在這裡實際代表這個軟體,隻要你修改軟體的哪怕一個比特位,它的Hash值都不一樣。這就是為什麼說叫它消息的指紋。Hash算法是非常重要的密碼學元件,在很多協定中廣泛使用。
Lauren: 明白,也就是說,每次放軟體到服務上,也需要計算一個Hash值放在一起,以友善将來驗證。
Haorui: 是的。
Lauren: 那麼我剛才說的CRC檢驗與Hash函數算法有啥差別呢?也就是Hash函數有還有啥特點呢?
Haorui: 對于Hash函數的輸入,任何長度的檔案都可以,輸出是一個固定長度的Hash值,根據不同的Hash算法,長度從32位到512位不等,而且Hash函數的計算速度要快。還有一點就是單向性,及給定一個Hash值,通過計算得出消息原文是不可能的。類于模運算,xmod 100 = 5,實際上是你是無法知道x的值,它的解是一個集合。
但最主要的特點就是,剛才己經講了,不同的檔案所産生的Hash值是不同的。
Lauren: 這個不可能完全做到。比如一個100M的檔案,計算出的Hash值為128位。一定存在很多個檔案也可以得到相同的Hash值。
Haorui: 是的。但是給定一個消息及消息的Hash值,去計算另一個與之具有相同的Hash值的消息是非常困難的。及設hash_val= Hash(mesage1), hash_val和message1是己知的,求解Hash(mesage1)= Hash(mesage2)中的message2?合格的Hash函數要保證你是不無法通過計算得出的,專業上這叫弱抗碰撞性。還有一個概念叫強抗碰撞性,及要找到兩個Hash值相同的消息在計算上不可行的。密碼學要使用的Hash函數必須具備這弱抗碰撞性和強抗碰撞性。
Lauren: 明白了,Hash函數算法長啥樣?
Haorui: 不同的Hash算法實作不一樣。看具體的标準吧。常用的單向散列函數有SHA1、SHA256、SHA384、MD4、MD5等。