官术网_书友最值得收藏!

2.1 什么是哈希函數

現在,我們可以看到一個網頁(見圖2.1),而下載(DOWNLOAD)按鈕占據該網頁的大部分空間。通過單擊下載(DOWNLOAD)按鈕,我們會跳轉到一個包含待下載文件的網站。在這個按鈕的下面有一長串難以理解的字符串:

f63e68ac0bf052ae923c03f5b12aedc6cca49874c1c9b0ccf3f39b662d1f487b

后面還有一串看起來像某種首字母縮略詞的字符(sha256sum:)。這個字符串看起來是不是有點眼熟呢?在生活中,我們可能也下載過附帶類似字符串格式的文件。

我們可以利用這個長字符串按照如下步驟來檢測文件的完整性:

(1)點擊按鈕來下載文件;

(2)采用SHA-256算法來計算下載文件的哈希值;

(3)將哈希函數的輸出(摘要)與網頁上顯示的字符串進行比較。

這個字符串還可以幫助我們驗證下載的文件是否正確。

圖2.1 該網頁鏈接到包含一個文件的外部網站。該網頁提供了該文件的哈希值,因為哈希值可以保證外部網站無法隨意修改文件內容而不被察覺。該文件的哈希或摘要確保了下載文件的完整性

注意:

哈希函數的輸出通常被稱為摘要(Digest)或哈希值(Hash)。本書將交替使用這兩個詞。其他書可能會稱哈希函數為校驗和(Checksum),但因為這個術語主要用于指代非密碼學的哈希函數,所以本書沒有使用這個名詞。我們只需要牢記,不同的代碼庫或文件會使用不同的術語。

當我們想要嘗試計算哈希值時,可以使用流行的OpenSSL庫。該庫提供了一個多用途的命令行接口(Command Line Interface,CLI),macOS之類的許多系統中自帶該命令行工具。例如,打開終端并輸入如下命令:

$ openssl dgst -sha256 downloaded_file
f63e68ac0bf052ae923c03f5b12aedc6cca49874c1c9b0ccf3f39b662d1f487b

通過上述命令,我們可以使用SHA-256哈希函數把輸入(下載的文件)轉化為一個唯一的標識符(命令返回的值)。執行這些額外操作的目的是,檢驗文件的完整性(Integrity)和真實性(Authenticity),保證下載的文件確實是我們想要的。

這些工作,要歸功于哈希函數的安全性質——抗第二原像性。這個術語意味著從這個哈希函數的長輸出f63e...中,我們無法推斷出另一個文件也可以通過相同的哈希函數得到相同的輸出f63e...。在實踐中,這意味著該摘要與正在下載的文件密切相關,沒有攻擊者能夠不知不覺地將原文件替換為不同的文件。

十六進制編碼

順便說一下,上面的字符串f63e...采用的是十六進制(Base16編碼,使用從0到9的數字和從a到f的字母來表示任意數據)表示形式。我們本可以用包含0和1的二進制編碼方法表示哈希函數的輸出,但這樣會占用更多空間。十六進制編碼允許我們將8比特(1字節)數編碼成2個字符。這種編碼方式具有可讀性強、占用的空間少的優點。我們還可以使用其他的編碼方法將二進制數據編碼成可讀字符,但十六進制編碼和Base64編碼是使用最多的兩種編碼方式。在Base系列編碼中,基越大,編碼二進制數據需要的字符數就越多。當然,如果用的基過大,我們可能就無法用已有的可讀字符編碼二進制數據。

請注意,這個長字符串由網頁的所有者控制,任何能夠修改該網頁的人都可修改該字符串。(如果不相信這一點,請花點兒時間思考一下原因。)因此,為了確保文件的完整性,我們需要信任包含摘要字符串的網頁、網頁的所有者以及獲取網頁頁面的安全機制,而不必信任包含下載文件的網頁。從這個意義上說,單獨使用一個哈希函數并不能提供完整性。因為下載文件的完整性和真實性來自文件摘要以及摘要的可信機制(在本例中為HTTPS)。我們將在第9章討論HTTPS,但現在我們先假設該協議允許我們與網站進行安全通信。

我們可以將哈希函數看作圖2.2中的黑匣子。我們的黑匣子接收一個輸入并產生一個輸出。

圖2.2 哈希函數可以接收任意長度的輸入(文件、消息、視頻等)并產生固定長度的輸出(例如,SHA-256算法的輸出為256比特)。對于同一個哈希函數,相同的輸入會產生相同的摘要或哈希值

哈希函數的輸入可以是任意大小,甚至可以是空值,而它的輸出的長度總是固定的,且具有確定性:給定相同的輸入,哈希函數總是產生相同的輸出。在我們的示例中,SHA-256始終提供256比特(32字節)的輸出,它的輸出終被編碼為64個十六進制字符。哈希函數的一個主要特性是無法求逆,也就是說無法從輸出中找到輸入。因此,我們說哈希函數是單向(One-way)的。

為了說明哈希函數在實踐中的工作原理,我們將使用OpenSSL命令行工具中的SHA-256哈希函數計算不同輸入的哈希值。在OpenSSL命令行工具中,SHA-256算法的輸入和輸出如下所示:

$ echo -n “hello” | openssl dgst -sha256
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 
$ echo -n “hello” | openssl dgst -sha256    ←--- 對同樣的輸入計算哈希值,會得到相同的輸出
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
$ echo -n “hella” | openssl dgst -sha256    ←--- 對哈希函數的輸入內容的細微修改會得到完全不同的哈希值
70de66401b1399d79b843521ee726dcec1e9a8cb5708ec1520f1f3bb4b1dd984
$ echo -n “this is a very very very very very very    ←--- 無論輸入的消息有多長,哈希函數輸出值的長度總是固定的
  ? very very very long sentence” | openssl dgst -sha256            
1166e94d8c45fd8b269ae9451c51547dddec4fc09a91f15a9e27b14afee30006

在2.2節中,我們將看到哈希函數的其他性質。

主站蜘蛛池模板: 岳阳市| 昔阳县| 英德市| 稻城县| 阜城县| 阜平县| 汉源县| 云林县| 衡水市| 竹北市| 双城市| 抚远县| 彩票| 巩留县| 五台县| 磴口县| 玛纳斯县| 麻栗坡县| 茌平县| 玉溪市| 门头沟区| 惠来县| 依安县| 沙湾县| 合水县| 日照市| 聂荣县| 平罗县| 华宁县| 洮南市| 临邑县| 朔州市| 萨嘎县| 铜鼓县| 罗定市| 东台市| 体育| 湟中县| 济南市| 化德县| 二手房|