天天看點

掃盲檔案完整性校驗——關于散列值和數字簽名

近期有網友在部落格中留言,希望俺介紹散列值校驗檔案的知識。是以俺幹脆寫一篇"檔案完整性校驗"的掃盲教程。由于本文是掃盲性質,盡量不涉及太技術化的内容。 

所謂的"完整性校驗",顧名思義,就是檢查檔案是否完整。那麼,什麼情況下會導緻檔案不完整捏?大概有如下幾種情況。 

1. 感染病毒 

比方說你的系統中了病毒,病毒感染了某個軟體安裝包或者某個可執行程式。那麼該檔案的完整性就被破壞了。 

2. 植入木馬/後門 

還有一種檔案不完整的情況,是被别有用心的人植入木馬或後門。比方說某些國内的軟體下載下傳站點,它們提供的 Windows 安裝CD光牒鏡像已經被安置了後門。 

3. 傳輸故障 

這種情況主要發生在網絡下載下傳時。因為網絡傳輸是有可能發生誤碼的(傳輸錯誤),另外還有可能下載下傳到快結束的時候斷線(下載下傳不完整)。這些情況就會導緻你下載下傳的檔案不完整。 

如今的上網環境相比當年的Modem撥号,已經有明顯改善。是以這種情況應該不多見了。 

這裡所說的"散列"是一種計算機算法,洋文叫做 Hash,有時候也根據音譯稱為哈希。 

雜湊演算法可以把 任意尺寸 的資料(原始資料)轉變為一個 固定尺寸 的"小"資料(叫"散列值"或"摘要")。 

對于某個具體的雜湊演算法,得到的散列值長度總是固定的。散列值的長度又稱"摘要長度"。 

以下是常見雜湊演算法的摘要長度 

CRC32  32比特(4位元組) 

MD5  128比特(16位元組) 

SHA1 160比特(20位元組) 

1. 不可逆性 

從剛才的描述看,散列似乎有點像壓縮。其實捏,雜湊演算法跟壓縮算法是完全不同滴。壓縮算法是可逆的(可以把壓縮後的資料再還原),而 雜湊演算法是不可逆的 。 

還有一些人把雜湊演算法稱為"加密算法",這也是不對的。因為加密算法是可逆的("加密"的逆操作就是"解密"),而雜湊演算法是不可逆的。 

2. 确定性 

通過某種雜湊演算法,分别對兩個原始資料計算散列值。如果算出來的散列值不同,那麼可以 100% 肯定這兩段資料是不同的——這就是"确定性"。 

但反過來,如果這兩段資料的散列值相同,則隻能說,這兩段資料 非常可能 相同。所謂的"非常可能",就是說,還達不到百分百。具體原因,請看下一節"散列函數的可靠性"。 

剛才說了,存在非常小的可能性,導緻兩段不同的原始資料,計算出相同的散列值。這種情況稱之為"散列碰撞"或"散列沖突"。 

散列碰撞的類型,大體上有兩種: 

1. 随機碰撞 

随機碰撞就像買×××中大獎,完全是出于小機率的偶然因素——你碰巧遇見兩個不同的資料(檔案),具有相同的散列值。 

理論上講,任何雜湊演算法都存在随機碰撞的可能性,隻是可能性有大有小。 

2. 人為碰撞 

人為碰撞就是說,有人(通常是惡意的攻擊者)故意制造散列碰撞,以此來騙過"基于散列值的完整性校驗"。 

1. 對于随機碰撞 

要避免随機碰撞,很簡單,隻需要選擇摘要長度足夠長的雜湊演算法。 

拿前面舉的3個例子。 

CRC32 的摘要長度是 32bit,也就說,最多可以表示 "2的32次方" 這麼多種可能性(也就是幾十億,數量級相當于地球總人口)。表面上看貌似很大,其實還不夠大。比如目前網際網路上的頁面總數就已經大大超過幾十億。如果對每個頁面計算 CRC32 散列,會碰到很多重複(碰撞)。 

而 MD5 的摘要長度是128bit,也就是 2的128次方。這個數字足夠大了。通俗地說,從宇宙誕生到宇宙毀滅,你都未必有機會碰見 MD5 的 随機 碰撞。而 SHA1 的摘要長度是160bit,那就更不用說了。 

2. 對于人為碰撞 

想避免人為碰撞,要同時兼顧兩個因素——雜湊演算法的摘要長度、雜湊演算法的優秀程度。"摘要長度"剛才已經解釋了。光說一下"算法的優秀程度"。 

如果某個雜湊演算法有缺陷(不夠優秀),那麼攻擊者就可以比較容易地構造出兩個 不同的 原始資料,但卻擁有 相同的 散列值。如此一來,就可以騙過基于雜湊演算法的完整性檢查。 

典型的例子就是 MD5,MD5算法在過去10多年裡曾經非常流行,但是前幾年被發現存在嚴重缺陷。是以,MD5 雖然随機碰撞的機率非常非常低,但人為碰撞的機率可不低。如果你比較注重安全性,盡量不要依賴 MD5 進行完整性校驗。 

如今,大夥兒的安全意識越來越高了。相應的,很多知名的軟體,除了在官網上提供下載下傳,還會相應提供下載下傳軟體的散列值。當你下載下傳好某個軟體之後,先在自己電腦裡計算一下散列值,然後跟官方網站提供的散列值對比一下。如果散列值一樣,通常就說明沒問題。再啰嗦一下,盡量不要用 MD5,改用 SHA1。 

下面,介紹幾個常用軟體的散列值頁面,便于大夥兒查詢 

微軟的産品 

到" 這個頁面 "可以查微軟釋出的所有産品的散列值。微軟的産品很多,先根據類型或名稱篩選,找到某産品後,點"詳細資訊",就可以看到 SHA1 散列值。 

Firefox 浏覽器 

打開如下連結,可以看到 Firefox 某個版本的 SHA1 清單(把連結中的 XXXX 替換為版本号,比如18.0.2)。這個清單很長,包括各種語言,各個平台。為了友善起見,你可以先算好 SHA1 散列值,然後到裡面搜尋該散列值 

https://ftp.mozilla.org/pub/mozilla.org/firefox/releases/ XXXX /SHA1SUMS 

前面說完了校驗的流程,最後再說一下校驗的工具。 

考慮到大部分讀者是 Windows 使用者,俺介紹一下微軟官方的 FCIV(全稱是 File Checksum Integrity Verifier)。這是一個小巧、綠色、免費的指令行工具,下載下傳頁面在" 這裡 "。 

因為是指令行工具,你需要先運作 CMD,出現 Windows 的指令行界面(黑視窗)之後,在其中使用該工具。下面是 FCIV 功能簡介。 

比如你有一個微軟的系統安裝CD光牒鏡像,位于 C:\download\Windows.iso 那麼,用如下指令可以計算該檔案的 SHA1 散列值 

fciv -sha1 C:\download\Windows.iso

FCIV 支援批量計算某個目錄下的檔案散列值。比方說,可以用如下指令可以計算 C:\download 目錄下的每一個檔案的 SHA1 

fciv -sha1 C:\download\

比如 C:\download 目錄下有很多檔案。俺想知道過一段時間之後,這些檔案是否被改過。那麼,可以先用如下指令,把該目錄中所有檔案的 SHA1 散列都存儲到某個 xml 檔案中(本例中,儲存到 C:\hash.xml,你也可以儲存到其它檔案名) 

fciv -sha1 C:\download\ -xml C:\hash.xml

過了一段時間後,你可以用如下指令,就可以看出哪些檔案被修改過。 

fciv -sha1 C:\download\ -xml C:\hash.xml -v

所謂的"數字簽名",通俗來說,就是采用某種技術手段來證明某個資訊确實是由某個機構(或某個人)釋出的。因為其用途有點類似于傳統的手寫簽字,是以稱之為"數字簽名"。 

數字簽名的技術實作需要依賴于"非對稱加密技術"和"數字證書體系"。關于"非對稱加密技術",考慮到篇幅,今天就不展開了;關于"數字證書",3年前寫過一篇掃盲(在" 這裡 "),有興趣的同學可以瞧一瞧,這裡就不再啰嗦了。 

數字簽名有很多種,大夥兒比較常見的是 Windows 平台下的數字簽名。如今大型 IT 公司(比如:微軟、Google、蘋果、等)或者是知名開源組織釋出的 Windows 軟體,安裝檔案通常都内置數字簽名。是以俺着重介紹 Windows 平台的數字簽名該如何校驗。 

大概從 Windows 2000開始,Windows 就支援在某個檔案尾部附加數字簽名,并且 Windows 的資料總管内置了對數字簽名的校驗功能。 

下面俺通過幾個截圖,簡單介紹一下:如何在資料總管中驗證數字簽名。 

比如,俺手頭有一個 Firefox 的安裝檔案(帶有數字簽名)。當俺檢視該檔案的屬性,會看到如下的界面。眼神好的同學,會注意到到上面有個" 數字簽名 "的标簽頁。如果沒有出現這個标簽頁,就說明該檔案沒有附帶數字簽名。 

選擇該标簽頁,出現如下界面。 

順便說一下,某些數字簽名中沒有包含"郵件位址",那麼這一項會顯示"不可用";同樣的,某些數字簽名沒有包含"時間戳",也會顯示"不可用"。不要緊張,這裡顯示的"不可用"跟數字簽名的有效性 沒關系 。 

一般來說,簽名清單中,有且僅有一個簽名。選中它,點" 詳細資訊 "按鈕。跳出如下界面: 

通常這個界面會顯示一行字:" 該數字簽名正常 "(圖中紅圈标出)。如果有這行字,就說明該檔案從出廠到你手裡,中途沒有被篡改過(是原裝滴、是純潔滴)。 

如果該檔案被篡改過了(比如,感染了病毒、被注入木馬),那麼對話框會出現一個警告提示" 該數字簽名無效 "(圖中紅圈标出),界面如下。一旦出現數字簽名無效,那這個檔案就不要再使用了。 

用上面的圖形化界面進行驗證,比較傻瓜化。但有一個缺點——如果你要驗證的檔案比較多,一個一個去點對話框,手會抽筋滴。是以,俺再介紹一下指令行的工具,适合進行批量驗證。 

這個指令行工具就是微軟官網提供的 SigCheck,由大名鼎鼎的 SysInternals 出品(SysInternals 已經被微軟收購)。跟前面提到的 FCIV 類似,它也是一個小巧、綠色、免費的指令行工具,下載下傳頁面在" 這裡 "。 

使用如下指令,可以批量檢查某個目錄下(包括多層嵌套子目錄)的所有可執行程式,并且把"無簽名"或者"簽名無效"的檔案列出來。 

sigcheck -u -e -s 某個目錄的路徑名

先提醒一下,檢查數字簽名的有效性本身就比較慢,如果目錄下的檔案很多,你要有足夠的耐心等它運作完畢。 

稍微補充一下,這個 SigCheck 指令還順便提供了散列值(指令格式如下),該功能可替代 FCIV 的頭兩個功能,可惜無法替代 FCIV 的第三個功能。 

sigcheck -h 某個目錄或檔案的路徑名

剛才聊了 Windows 平台滴。但是,切莫以為隻有 Windows 平台才提供數字簽名——其它的數字簽名工具還有好幾種。名氣比較大的數字簽名工具當屬 PGP/GPG。這兩個縮寫就像繞密碼,很容易搞混。PGP 是商業軟體,而 GPG 是 GnuPG 的縮寫,是 GNU 的開源項目。後者是前者的開源替代品,兩者的功能基本相容。 

這倆玩意兒的功能很強悍,校驗數字簽名對它倆隻是小菜一碟。考慮到大夥兒平時較少碰到 GPG 的簽名,俺今天就偷懶一下,暫不介紹。以後如果有空,再專門寫一篇文章介紹 PGP/GPG 的各種功能和使用場景。 

原文  http://program-think.blogspot.com/2013/02/file-integrity-check.html

轉載:http://www.tuicool.com/articles/vIneYr

繼續閱讀