每個人都下載檔案,大家有沒有想過,檔案可能是假的,尤其來自網盤或專門的下載站。
本文就來談談如何識別檔案的真假。
一、XcodeGhost 事件
我們從一件真實的事件說起。
2015年9月,蘋果手機的一些 App 被發現向可疑網站傳送資料。進一步調查確認,可疑程式碼是 Xcode 打包時植入的。也就是說,開發者的程式設計工具 Xcode 被動過手腳了。
騰訊的安全團隊公佈調查報告,應用商店的前 5000 名應用有76個被感染。360 應用商店檢查後發現,共有1076個 App 被感染,包括微信、網易雲音樂、滴滴叫車、高德地圖、12306、同花順等熱門應用。蘋果公司將所有被感染的版本,都從官方軟體商店下架了。這個事件就稱為 XcodeGhost 事件。
國家網際網路應急中心專門發出了預警通知。
追查下去,那些動過手腳的 Xcode 都不是從官方渠道下載的,而是來自網盤或下載站。一個網名"coderfun"的人,在各種 iOS 開發者論壇或者微博留言,引誘其他開發者下載修改過的 Xcode,版本從 Xcode 6.1 到 6.4。
事後,這位 coderfun 發出致歉公告,表示這只是自己的一次實驗,沒有惡意。但是,這個事件足以引起警惕,任何下載的檔案都不一定安全,很可能被修改過或植入惡意程式碼。
二、軟體的防偽措施
為了防止來源不明的軟體,很多平臺都有簽名機制。軟體釋出必須由認證過的開發商,使用平臺的金鑰簽名。如果使用者安裝未簽名的軟體,平臺會彈出警告,阻止安裝。下面就是 MacOS 的警告。
但是,不可能所有開發者都去認證,尤其是認證要收費。而且,使用者對這種警告不在乎,一般都會忽略或手動關閉。所以,這種做法的效果不明顯。
目前的常用做法是,軟體釋出時,同時給出雜湊碼和簽名檔案。前者保證沒有被第三方修改,後者保證確實出自原始作者。
舉例來說,Linux 的發行版 Manjaro 除了提供原始的 iso 檔案,還提供另外三個檔案:sha1 雜湊檔案、sha 256 雜湊檔案和 sig 簽名檔案。 它們保證了軟體的真實性。
三、雜湊碼驗證
雜湊碼指的是,檔案內容經過雜湊函式的計算,會返回一個獨一無二的字串。哪怕原始內容只改動一個位元組,雜湊碼也會完全不同。使用者下載軟體後,只要計算一下雜湊碼,再跟作者給出的雜湊碼比較一下,就會知道軟體有沒有被改動。
目前,常用的三種雜湊函式是 MD5、SHA1 和 SHA256。其中,SHA256 最安全,SHA1 次之,MD5 墊底。一般來說,軟體至少會提供其中一種雜湊碼。
下面是雜湊碼的驗證方法。
(1)Linux 系統
Linux 系統直接用md5sum
、sha1sum
、sha256sum
這三個命令,計算雜湊碼。
$ md5sum foo.zip $ sha1sum foo.zip $ sha256sum foo.zip
上面命令返回檔案foo.zip
的三種雜湊碼。使用者再跟作者給出的雜湊碼比對。如果不一致,檔案就是被改動了,或者沒有完整下載。
有時,就像前面 Manjaro 的例子,雜湊碼不是寫在網頁上,而是作為一個單獨的文字檔案下載。這時可以使用-c
引數。
$ md5sum -c foo.zip.md5file $ sha1sum -c foo.zip.sha1file $ sha256sum -c foo.zip.sha256file
上面命令會返回雜湊碼的比對結果,直接告訴使用者是否一致。
(2)Mac 系統
MacOS 的驗證命令需要自己安裝。
$ brew install md5sha1sum
執行上面命令以後,md5sum
和 sha1sum
就可以使用了。至於 sha256sum
要用 shasum -a256
命令代替。
(3)Windows 系統
Windows 可以下載安裝免費軟體 Quick hash 或者 Raymond's MD5 & SHA Checksum Utility。其中,Quick hash 是跨平臺的,還支援 Linux 和 MacOS。
四、簽名驗證
雜湊碼只能保證檔案內容沒有修改,但是雜湊碼本身也有可能仿冒,完全可能連帶原始檔案一起造假。
檔案簽名能解決這個問題。軟體釋出時,作者用自己的私鑰,對釋出的軟體生成一個簽名檔案(Manjaro 例子的 sig 檔案),使用者使用作者的公鑰驗證簽名檔案。
第一步,下載公鑰。
軟體的官網一般都會給出作者公鑰的下載方法。比如,Manjaro 就可以從 GitHub 倉庫下載公鑰。
$ wget github.com/manjaro/packages-core/raw/master/manjaro-keyring/manjaro.gpg
公鑰也有可能放在專門的公鑰伺服器,這時可以使用gpg
命令在從公鑰伺服器下載。
$ gpg --keyserver hkp://eu.pool.sks-keyservers.net --search-keys [公鑰 ID]
上面命令會列出搜尋結果,讓你選擇是否下載某一個公鑰。--keyserver
引數指定公鑰伺服器,search-keys
引數給出搜尋引數,可以是作者的名稱,也可以是公鑰的指紋。
gpg
命令在 Linux 下可以直接使用,MacOS 和 Windows 需要安裝 GnuPG。
第二步,匯入公鑰。
下載得到公鑰後,將其匯入作業系統。
$ gpg --import [公鑰檔案]
如果有完整的公鑰指紋,gpg
命令的 --recv-key
引數可以直接從伺服器匯入公鑰。
$ gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-key "27DE B156 44C6 B3CF 3BD7 D291 300F 846B A25B AE09"
第三步,驗證簽名。
匯入公鑰以後,就可以驗證簽名檔案(字尾名為 sig
的 檔案)了。
# 用法一 $ gpg --verify [簽名檔案] # 用法二 $ gpg --verify [簽名檔案] [原始檔案]
上面命令的兩種用法,效果是一樣的。但是,用法一要求原始檔案與簽名檔案同名,且在一個目錄下。比如,簽名檔案是foo.iso.sig
,原始檔案必須是同目錄下的foo.iso
。
簽名檔案一般包括完整的公鑰指紋,所以也可以跳過上面的第一步和第二步,直接從公鑰伺服器獲取公鑰,驗證簽名。
$ gpg --keyserver-options auto-key-retrieve --verify [簽名檔案]
(完)