任何形式的網絡服務都存在安全風險,如何將風險降到最低是互聯網普遍關注的問題。通常,網絡安全措施的實現方法有數據加密、數字簽名、身份認證、防火牆和入侵檢測等。其中數據加密是防止未經授權的用戶訪問敏感信息的手段,而研究數據加密的科學我們稱之爲密碼學(Cryptography)。
密碼學有着悠久而光輝的歷史,古代的軍事家已經用密碼傳遞軍事情報了,而現代計算機的應用和計算機科學的發展又爲這一古老的科學注入了新的活力。現代密碼學是經典密碼學的進一步發展和完善。由於加密和解密此消彼長的鬥爭永遠不會停止,這門科學還在迅速發展之中。
鑑於目前全球網絡處理的數據量大幅增加,計算機科學家一直在尋找加速數據訪問並確保數據安全交換的方法。當前常用的一種安全加密技術哈希(Hash)函數,也稱散列函數。今天我們來詳細聊聊散列函數。
什麼是散列函數
散列函數,首先我們先來看下散列。散列的釋義是切碎或打亂某些東西,也是關於散列函數的一種描述。沒錯,將數據 “打亂”,轉換成其他數值。並且無論數據輸入多長,輸出值總是相同的長度。
散列函數將任意長度的字符串轉換爲固定長度的字符串,這個固定長度的字符串稱爲散列值。散列值是一段數據唯一的、緊湊的表示形式。如果對一段明文只更改其中的一個字母,隨後的散列變換都將產生不同的散列值。因爲找到散列值相同的兩個不同的輸入在計算上是不可能的,所以數據的散列值可以檢驗數據的完整性。
在上面的散列函數示例中,所有不同的密碼在存儲到數據庫之前都被轉換爲固定長度的字符串。這些輸出字符串無法轉換到原來的實際密碼。
散列值是散列函數和算法計算出來的結果。散列值是唯一的,就像人的指紋一樣。如果採用小寫字母 “a” 到 “f” 和數字 “0” 到 “9” 並定義一個長度爲 64 個字符的散列值,則有 1.1579209e+77 個可能的輸出值,即 70 後面跟 24 個零!這表明即使使用較短的字符串,仍然可以生成一個長度可以接受的指紋。
使用 SHA256 函數生成的散列值始終具有相同的長度,無論輸入字符串中字符的數量和類型如何。
SHA256-Hash for:apple
3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b
SHA256-Hash for:pear
97cfbe87531abe0c6bac7b21d616cb422faaa158a9f2ae7e8685c79eb85fc65e
SHA256-Hash for:plum
0467255695084cc12ffe0c55105907f74a9c189314b9fe87b878eb6fee787b99
SHA256-Hash for:strawberry
5e737f891db1175442a39fde73e51d781a545506d71c95477a6deb5988bd7f9a
上面示例中的散列值只需幾行 PHP 代碼即可生成:
<?php
echo hash('sha256', 'apple');
?>
散列函數可以用於計算機科學的許多領域。例如:
- 服務器和瀏覽器之間的通信加密,併爲互聯網應用程序和數據緩存生成會話 ID
- 保護敏感數據,例如密碼、付款訂單等
- 向電子郵件中添加數字簽名
- 通過查找功能定位相同或相似的數據集
散列函數的設計特點
哈希的核心是一個數學函數,它對兩個固定大小的數據塊進行運算以創建哈希代碼。該散列函數構成散列算法的一部分。每個數據塊的大小因算法而異。通常,塊大小從 128 位到 512 位。下圖演示了哈希函數:
散列算法涉及上述散列函數的輪次,如分組密碼。每輪採用固定大小的輸入,通常是最新消息塊和上一輪輸出的組合。重複此過程所需的輪數以散列整個消息。哈希算法的示意圖如下圖所示:
因爲,第一個消息塊的哈希值成爲第二個哈希操作的輸入,其輸出改變第三個操作的結果,依此類推。這種效應稱爲散列的雪崩效應。雪崩效應導致兩條消息的散列值大相徑庭,即使只有一位數據不同,結果也完全不同。
正確理解哈希函數和算法的區別:
- 哈希函數通過對兩塊固定長度的二進制數據進行運算生成哈希碼。
- 散列算法是使用散列函數的過程,指定消息將如何分解以及如何將先前消息塊的結果鏈接在一起。
散列函數的設計具有以下屬性:
單向性
一旦生成散列值,就不可能將其轉換回原始數據。例如,在上面的示例中,一定無法將“$P$Hv8rpLanTSYSA/2bP1xN.S6Mdk32.Z3” 轉換回 “susi_562#alone”。
無碰撞/無衝突
對於無衝突的散列函數,沒有兩個字符串可以映射到相同的輸出散列值。換句話說,每個輸入字符串都必須生成唯一的輸出字符串。這種類型的散列函數也稱爲密碼散列函數。在上面的哈希函數示例中,沒有相同的哈希值產生,即輸出字符串之間沒有 “衝突” 。
速度快如閃電
如果散列函數計算散列值的時間太長,則也沒有多大用處。因此,散列函數必須非常快。在數據庫中,散列值存儲在散列表中以確保快速訪問。
流行的散列函數
接下來,我們來簡單看看有哪些流行的散列函數。
消息摘要(MD)
多年來,MD5 一直是最受歡迎和廣泛使用的哈希函數。
- MD 系列包括散列函數 MD2、MD4、MD5 和 MD6。它被採納爲 Internet 標準 RFC 1321。它是一個 128 位的散列函數。
- MD5 摘要已廣泛用於軟件領域,以保證傳輸文件的完整性。例如,文件服務器通常會爲文件提供預先計算的 MD5 校驗和,以便用戶可以將下載文件的校驗和與其進行比較。
- 2004 年,MD5 發現了衝突。據報道,使用計算機集羣的分析攻擊僅在一個小時內就成功了。這種碰撞攻擊導致 MD5 受損,因此不再推薦使用。
安全散列函數(SHA)
HA 系列包含四種 SHA 算法;SHA-0、SHA-1、SHA-2 和 SHA-3。雖然來自同一個家庭,但結構不同。
- 最初的版本是 SHA-0,一個 160 位的散列函數,由美國國家標準技術研究院(NIST)於 1993 年發佈。在當時它並沒有很流行。1995 年,SHA-1 出現了,用來糾正一些 SHA-0 的缺點。
- SHA-1 是現有 SHA 散列函數中使用最廣泛的。它用於多種廣泛使用的應用程序和協議,包括安全套接字層(SSL)的安全性。
- 2005 年,發現了一種在實際時間範圍內找到 SHA-1 衝突的方法,這使得 SHA-1 的能力受到質疑。
- SHA-2 系列還有四種 SHA 變體,SHA-224、SHA-256、SHA-384 和 SHA-512,具體取決於其哈希值中的位數。
- SHA-2 是一個強大的哈希函數。雖然有很大的不同,但它的基本設計仍然遵循 SHA-1 的設計。因此,NIST 呼籲新的競爭性哈希函數的設計。
- 2012 年 10 月,NIST 選擇 Keccak 算法作爲新的 SHA-3 標準。Keccak 提供了許多優點,例如高效的性能和良好的攻擊抵抗力。
RIPEMD
RIPEMD 是 RACE Integrity Primitives Evaluation Message Digest 的縮寫。這種散列函數由開放研究社區設計,通常被稱爲歐洲散列函數族。
- 該家族包括 RIPEMD、RIPEMD-128 和 RIPEMD-160。該算法還存在 256 位和 320 位版本。
- 原始 RIPEMD(128 位)基於 MD4 中使用的設計原則,被發現其提供的安全性有缺陷。RIPEMD 128 位版本作爲快速修復替代品出現,以修復原始 RIPEMD 上的漏洞。
- RIPEMD-160 是改進版本,也是該系列中使用最廣泛的版本。256 位和 320 位版本減少了意外碰撞的可能性,但與 RIPEMD-128 和 RIPEMD-160 相比安全性並沒有更高。
Whirlpool
這是一個 512 位哈希函數。
-
它源自高級加密標準(AES)的修改版本。其中一位設計師是 AES 的共同創建者 Vincent Rijmen。
-
Whirlpool 已經發布三個版本:即 WHIRLPOOL-0、WHIRLPOOL-T 和 WHIRLPOOL。
散列函數的應用
基於其密碼學特性,散列函數有如下應用場景:
密碼存儲
散列函數爲密碼存儲提供保護。
- 大多數登錄過程都沒有將密碼以明文形式存儲,而是將密碼的散列值存儲在文件中。
- 密碼文件由形式爲 (user id, h(P)) 的對錶組成。
- 登錄過程如下圖所示:
- 入侵者只能看到密碼的散列值,即使他得到了密碼。既不能直接使用散列值登錄,也不能從散列值中推導出密碼,因爲散列函數具有單向性。
數據完整性檢查
數據完整性檢查是散列函數最常見的應用。它用於生成數據文件的校驗和。應用程序可以向用戶保證數據的準確性。該過程如下圖所示:
完整性檢查可幫助用戶檢測原始文件所做的任何更改。但是,它不對原創性提供任何保證。攻擊者無需修改文件數據,而是可以更改整個文件並一起計算新的哈希值,將其發送給接收方。此完整性檢查應用程序僅在用戶確定文件的原創性時纔有用。
哈希函數和網站
使用 SSL 加密的數據傳輸,當 Web 服務器收到請求時,它會將服務器證書發送到用戶的瀏覽器。然後使用散列函數生成會話 ID,並將其發送到服務器進行解密和驗證。如果服務器批准會話 ID,則建立加密的 HTTPS 連接並可以交換數據。所有交換的數據包也都是加密的。
哈希值還用於加密緩存數據,以防止未經授權的用戶使用緩存訪問登錄和付款等敏感數據。使用 SFTP 協議的 FTP 服務器和客戶端之間的通信也以類似的方式工作。
數字簽名
電子郵件通過專門設計用於傳輸此類消息的服務器發送。使用散列函數生成的密鑰也用於向消息添加數字簽名。
在電子郵件中添加數字簽名就像在手寫的信件上簽名——簽名一次,這個簽名就是獨一無二的。
發送帶有數字簽名的電子郵件的步驟是:
- 小美(發件人)將她的消息轉換爲哈希值並使用她的私鑰加密哈希值。這個加密的哈希值就是數字簽名。
- 小美將電子郵件和數字簽名發送給收件人小帥。
- 小帥使用相同的散列函數生成消息的散列值。他還使用小美的公鑰解密散列值並比較兩個散列值。
- 如果這兩個哈希值匹配,小帥就知道小美的消息在傳輸過程中沒有被篡改。
注意,數字簽名證明了消息的完整性,但實際上並沒有對其進行加密。如果要發送機密數據,那麼最好對其進行加密並使用數字簽名。
散列函數用於提高互聯網通信的安全性,現在已經開發了許多高度複雜的標準。然而,黑客們也意識到了這一點,並不斷想出更高級的黑客技術來破解它。技術不斷變革,將來還會有什麼樣的高級加密算法出現呢?未來,讓我們拭目以待!