Linux上驗證下載檔案的真實性和完整性

51CTO發表於2014-11-05

你從網際網路上下載了某個檔案(比如安裝程式、ISO映像檔案或壓縮檔案)後,該檔案可能因各種錯誤情形而遭到損壞,比如由於網路連線上的傳輸錯誤、下載受到中斷、儲存硬體有故障、檔案系統錯誤等。拋開此類錯誤情形不說,檔案還有可能被攻擊者在下載過程中或下載前惡意篡改。比如說,攻擊者對認證中心做手腳後,就能發動中間人(MITM)攻擊,引誘你從假冒的HTTPS網站下載感染了惡意軟體的檔案。

為了保護自己遠離這些種類的問題,你從網際網路下載檔案時,我們常常建議驗證檔案的真實性和完整性。尤其是你下載了相當敏感的檔案(比如作業系統映像檔案、應用程式二進位制程式碼和可執行的安裝程式等)後,盲目地相信已下載檔案可不是一個好習慣。

想驗證已下載檔案的完整性,一個快速而簡單的辦法就是,使用各種校驗和工具(比如md5sum、sha256sum和cksum),計算並比較校驗和(比如MD5、SHA或CRC)。不過,校驗和很容易遭到碰撞攻擊,而且無法用來驗證檔案的真實性(即所有者)。

如果你既想驗證已下載檔案的真實性(所有者),又想驗證檔案的完整性(內容),就要改而依賴加密簽名。我在本教程中將介紹如何使用GnuPG(GNU隱私保護),檢驗檔案的真實性和完整性。

在這個例子中,我要驗證可從https://onionshare.org下載的一個磁碟映像檔案。在該網站上,檔案釋出者提供了官方公鑰,還提供了用於驗證的指紋。

在Linux上如何驗證已下載檔案的真實性和完整性?

至於有待下載的檔案,釋出者還提供了相應的PGP簽名。

在Linux上如何驗證已下載檔案的真實性和完整性?

安裝GnuPG,生成金鑰對

我們不妨先將GnuPG安裝到你的Linux系統上。

在Debian、Ubuntu及其他Debian衍生版上:

$ sudo apt-get install gnupg

在Fedora、CentOS或RHEL上:

$ sudo yum install gnupg

安裝完畢後,生成金鑰對,你在本教程中要用到該金鑰對。

$ gpg --gen-key

在Linux上如何驗證已下載檔案的真實性和完整性?

金鑰生成過程中,會要求你提供姓名和電子郵件地址,以及保護你私鑰的密碼。你還可以選擇金鑰對何時到期(預設情況下沒有到期日)。金鑰生成過程可能需要幾分鐘或更久,長短取決於你選擇的金鑰大小(1024位到4096位),因為它需要收集足夠數量的隨機性資料,這些資料來自你的桌面活動(比如鍵盤鍵入、滑鼠移動、磁碟訪問)。

金鑰生成完畢後,公鑰和私鑰都將儲存在~/.gnupg目錄中,供之後使用。

在Linux上如何驗證已下載檔案的真實性和完整性?

 

匯入檔案所有者的公鑰

驗證已下載檔案的第一步是,匯入檔案所有者的公鑰,與所有者建立信任關係則是可選步驟。

首先,下載檔案所有者的公鑰:

$ wget https://onionshare.org/signing-key.asc

然後繼續使用gpg命令,將公鑰匯入到你的金鑰環:

$ gpg --import signing-key.asc

在Linux上如何驗證已下載檔案的真實性和完整性?

一旦所有者的公鑰匯入完畢,它會輸出一個金鑰編號(比如“EBA34B1C”),如上所示。記下這個金鑰編號。

現在,執行這個命令,檢查已匯入公鑰的指紋:

$ gpg --fingerprint EBA34B1C

在Linux上如何驗證已下載檔案的真實性和完整性?

你會看到公鑰的指紋串。將該指紋串與網站上顯示的指紋進行比對,看看兩者是否匹配。

通常來說,驗證公鑰的所有者確實是他或她聲稱的那個人必須經歷比簡單的指紋比對更嚴格的過程,因為網站有可能經過偽造,以便與指紋匹配。只有金鑰已經過了全面審查,確實屬於某個人(比如你見過那個人,通過電話聊了聊,以證實對方的身份,等等),才可以信任對方的公鑰。

一旦你通過另外的一些手段驗證了公鑰的有效性,並決定信任公鑰,就可以明確將你的信任賦予該金鑰,如下所示。要注意:這一步是可選的,不需要你在使用前賦予明確的信任。

$ gpg --edit-key EBA34B1C

這個命令會顯示GPG提示符:

在Linux上如何驗證已下載檔案的真實性和完整性?

在GPG提示符下鍵入“trust”,這會讓你可以選擇該金鑰的信任級別:從1到5。

在Linux上如何驗證已下載檔案的真實性和完整性?

在這裡,我決定賦予信任“4”。之後,鍵入“sign”,用你自己的私鑰來對它簽名,然後在GPG提示符下鍵入“save”:

在Linux上如何驗證已下載檔案的真實性和完整性?

同樣,這種明確將信任賦予公鑰的方式不是必需的;通過僅僅匯入金鑰表明絕對信任常常就夠了。

將“完全”信任賦予金鑰帶來的影響是,如果另一個金鑰X用這個完全信任的金鑰來簽名,金鑰X也被你認為是有效的。通常而言,金鑰驗證依賴一種名為“信任網路”(web of trust)的複雜機制。

回到本教程,現在不妨檢驗已匯入金鑰列表。

$ gpg --list-keys

在Linux上如何驗證已下載檔案的真實性和完整性?

你應該至少會看到兩個金鑰:一個是深度為0、終極信任(“1u”)的金鑰;另一個是深度為1、完全信任(“1f“)的金鑰,後者是由你自己早些時候簽名的金鑰。

驗證檔案的真實性/完整性

一旦你使用檔案所有者的公鑰與對方建立起了信任關係,我們現在就可以準備驗證你從所有者那裡下載的某個檔案的真實性和完整性了。

在我們這個例子中,檔案所有者分開發布了檔案和相應的PGP簽名(*.asc)。簽名的作用就是驗證檔案,並給檔案加上時間戳。

一個典型的簽名(*.asc)看起來如下。

—–BEGIN PGP SIGNATURE—–

iQIcBAABCgAGBQJUJGhsAAoJEP1yCtnro0sc1jUP/ixNY/lKdrcMIAUoqlWKNE8f

sj4SFiwREMew76w66GASDF03fa5zPX6EsS2kucgx8ZsfEiSmN5T0y2P/aSaXwZqF

kywZVEzirKtca5AJ4DBzu6qrt9GgSw6JBJVv1oBJCMNyO+eAj341paR3MudvnyQz

H/N5tc4Qcilzy6M184opGIzy4ipEmMXfLHsd7WJpAyn+tO/z3uhh9NkNuygZpaFr

olpSWPE8revdDJyfMfSmb3ZrFmhLn7FCEltOi+a7SluvrMclizfnbec9rgLJtjo0

CPDZY7tsWmmL0DA3VvpMVqGvkg/Dyhpn2IIDrNaLAlvGQ5aovf+4tjad5IHvyaWx

4Gds93G6Hqvv5RwGx7OR3hgt2o0Y+qFsVDxVnPxerGhXeJXHzSDwLQMpdj9IoSU

Ae/53XXnxqSN6POZcwHiHvbsv0pdlg0Ea0dDAAN0ZeINNyZf1R0tLjWkcgpvGCtv

qkJuYFF9W9cWHraPY2ov5Hs/JZzPcG0eVpnDdzfOOH1gDKADq9A5D2X5QJCulsh9

WwU3X+E43OqIsoRzBucItD9HhZbEH7t8Q0xAqnAkgU3hriZp3dN4cnMfhM6I9hli

EmpSpLKCceMexu2o9QgzGXVm+AGZJe4QkuwAhRIccp5JDMVny61UlKTasjy6co8h

5GBhhYybPEFM+G1BODMd

=c9wo

—–END PGP SIGNATURE—–

我們不妨下載檔案及其簽名:

$ wget https://onionshare.org/files/0.6/OnionShare.dmg $ wget https://onionshare.org/files/0.6/OnionShare.dmg.asc

現在,驗證已下載檔案的PGP簽名。

$ gpg --verify OnionShare.dmg.asc OnionShare.dmg

在Linux上如何驗證已下載檔案的真實性和完整性?

如果該命令的輸出裡面含有“Good signature from ”,這表明已下載的.dmg檔案已成功通過了驗證。要是已下載檔案在簽名生成後以任何一種方式而遭到篡改,驗證就會失敗。

現在你大可放心,可以信任那個已下載檔案了。

相關文章