1、概述
哈希算法(Hash Algorithm),又稱散列算法,是一種將任意長度的輸入數據(明文)轉換為固定長度的輸出(哈希值/摘要)的數學算法。
哈希值通常被稱為摘要(Digest)。
其核心思想是通過單向函數將數據映射到一個較短的、固定長度的字符串,同時保證不同的輸入生成不同的哈希值(理想情況下)。
2、主要特點
(1)、單向性(不可逆)
- 特性:無法從哈希值反推出原始輸入數據。
- 用途:確保數據隱私(如密碼存儲)。
- 示例:SHA-256(“Hello”)生成固定長度的哈希值,但無法通過哈希值還原出"Hello"。
(2)、固定輸出長度
- 特性:無論輸入多長,輸出長度固定(如 SHA-256 的輸出為 256 位)。
- 用途:便于存儲和傳輸。
(3)、確定性
- 特性:相同的輸入始終生成相同的哈希值。
- 用途:驗證數據完整性。
(4)、高效性
- 計算哈希值的速度非常快。
(5)、抗碰撞性(Collision Resistance)
- 特性:找到兩個不同輸入生成相同哈希值的難度極大(理論上不可能)。
(6)、雪崩效應(Avalanche Effect)
- 特性:輸入微小變化(如一個比特)會導致哈希值劇烈變化。
- 用途:確保數據篡改可檢測。
3、工作原理
(1)、基本流程
- 輸入處理:將任意長度的輸入數據(如文件、密碼)轉換為二進制格式。
- 填充與分塊:將輸入數據分割為固定大小的塊(如 SHA-256 分塊為 512 位)。
- 初始化變量:設置初始哈希值(如 SHA-256 使用前 8 個素數的平方根)。
- 主循環處理:對每個數據塊進行復雜的數學運算(如混淆、擴散操作)。
- 輸出哈希值:最終生成固定長度的哈希值。
(2)、沖突與解決
- 沖突(Collision):不同輸入生成相同的哈希值。
- 解決方法:
- 加鹽(Salting):在輸入中添加隨機值(鹽),防止彩虹表攻擊(如密碼存儲)。
- 虛擬節點:在分布式系統中,通過虛擬節點減少哈希沖突(如一致性哈希)。
4、應用場景
(1)、數據完整性校驗
- 用途:驗證文件或數據未被篡改。
- 示例:
- 下載軟件或文件時,可以通過比較官方提供的哈希值與本地計算得到的哈希值來確保文件未被篡改。
- 數據庫備份完整性校驗。
(2)、密碼存儲
- 用途:將密碼哈希后存儲,即使數據庫泄露,攻擊者也無法直接獲取明文密碼。
- 最佳實踐:
- 加鹽哈希:對每個密碼添加唯一鹽值(如bcrypt、PBKDF2)。
- 慢哈希:使用計算密集型算法(如bcrypt)抵御暴力破解。
解釋下加鹽處理流程:
[1]、存儲密碼的步驟
- 步驟1:生成鹽值
使用加密安全的隨機數生成器(如 SecureRandom)為每個用戶生成唯一的鹽值。鹽值長度建議至少為 16 字節。 - 步驟2:加鹽并哈希
將鹽值與用戶輸入的密碼拼接,再通過安全哈希算法(如 BCrypt、Argon2、SHA-256)生成哈希值。
示例公式:
哈希值 = hash(密碼 + 鹽值) - 步驟3:存儲鹽值和哈希值
將鹽值和哈希值一起存儲在數據庫中(鹽值可明文存儲,無需加密,密碼存儲為hash(原始密碼 + 鹽值)的摘要)。
[2]、校驗密碼的步驟
- 步驟1:獲取鹽值和存儲的哈希值
用戶登錄時,從數據庫中讀取該用戶的鹽值和哈希值。 - 步驟2:重新哈希
將用戶輸入的密碼與存儲的鹽值拼接,再次通過相同哈希算法生成新的哈希值。 - 步驟3:比對哈希值
將新生成的哈希值與數據庫中存儲的哈希值進行比較,若一致則驗證成功。
(3)、數字簽名
- 用途:結合非對稱加密(如 RSA)生成簽名,確保數據來源和完整性。
- 流程:(先hash在加密,先解密在重新hash)
- 發送方首先對消息進行哈希運算,然后使用自己的私鑰對哈希值進行加密形成簽名。
- 接收方收到消息后,先解密簽名獲得哈希值,并重新計算消息的哈希值進行比對,以此驗證消息的真實性和完整性。
(4)、唯一標識
- 用途:生成數據的唯一指紋(如 Git 版本控制)。
- 示例:區塊鏈中的每個區塊都包含前一個區塊的哈希值,形成了鏈式結構,保證了數據的不可篡改性。
(5)、分布式系統(一致性哈希)
- 用途:在分布式存儲或緩存中,均勻分配數據到節點。
- 特點:
- 減少數據遷移:節點增減時僅影響附近節點的數據。
- 虛擬節點:通過虛擬節點(如將物理節點映射為多個邏輯節點)平衡負載。
5、分類
1、MD5 (Message-Digest Algorithm 5) (不推薦)
- 概述:MD5是最著名的哈希算法之一,由Ronald Rivest設計,用于生成128位(16字節)的哈希值。
- 應用場景:
- 文件完整性檢查
- 密碼存儲(已不再推薦)
- 安全性問題:
- 易受碰撞攻擊影響,即可以輕易找到兩個不同的輸入產生相同的哈希值。
- 不再被認為是安全的,特別是在密碼存儲和認證方面。
2、SHA家族 (Secure Hash Algorithm Family)
-
SHA-1:(不推薦)
- 概述:生成160位(20字節)的哈希值。
- 安全性問題:與MD5類似,存在理論上的碰撞攻擊,已被證明不夠安全。
-
SHA-2(包括SHA-256, SHA-384, SHA-512等):(當前主流SHA-256)
- 概述:SHA-2是SHA-1的繼承者,提供了更高的安全性和更大的輸出空間(如SHA-256生成256位的哈希值)。
- 應用場景:
- 數字簽名
- 安全通信協議(如TLS/SSL)
- 區塊鏈技術(比特幣使用SHA-256)
- 安全性:目前沒有有效的攻擊方法,被廣泛認為是安全的。
-
SHA-3:
- 概述:作為SHA-2的后繼標準發布,但采用了完全不同的設計結構(海綿構造),以提供額外的安全保障。
- 應用場景:適用于需要高安全性的場景,盡管SHA-2仍然被認為足夠安全。
3、BLAKE 和 BLAKE2
-
BLAKE:
- 概述:一種基于HAIFA框架設計的哈希函數,最初是為了NIST SHA-3競賽而開發。
-
BLAKE2:
- 概述:BLAKE2是BLAKE的一個改進版本,速度更快且更加靈活,安全性高,支持多種輸出長度(如BLAKE2b生成512位哈希值)。
- 應用場景:
- 高效的數據完整性校驗
- 密碼派生函數(例如Argon2中使用BLAKE2b),密碼庫
- 區塊鏈
4、其他哈希算法
-
RIPEMD系列:
- 概述:另一種哈希算法家族,最初由歐洲RIPE項目開發。
- 應用場景:較少見于主流應用,但在某些特定場合下使用。
-
CRC32:
- 特點:簡單快速,但非加密安全。
- 用途:數據校驗(如文件傳輸)。
常見算法對比:
6、代碼示例
(1)、SHA-256 實現
import java.security.MessageDigest;public class SHA256Example {public static String sha256(String input) {try {MessageDigest digest = MessageDigest.getInstance("SHA-256");byte[] hash = digest.digest(input.getBytes());// 轉換為十六進制字符串StringBuilder hexString = new StringBuilder();for (byte b : hash) {String hex = String.format("%02x", b);hexString.append(hex);}return hexString.toString();} catch (Exception e) {throw new RuntimeException(e);}}
}
(2)、加鹽哈希(BCrypt)
import org.mindrot.jbcrypt.BCrypt;public class PasswordHashing {public static String hashPassword(String password) {// 生成鹽值并哈希密碼(工作因子 12 控制計算速度)return BCrypt.hashpw(password, BCrypt.gensalt(12));}public static boolean verifyPassword(String password, String hashed) {return BCrypt.checkpw(password, hashed);}
}
7、總結注意
(1)、哈希算法的核心價值
- 數據完整性:通過哈希值驗證數據未被篡改。
- 隱私保護:單向性確保密碼等敏感信息安全存儲。
- 高效性:固定輸出長度便于快速比較和存儲。
(2)、選擇哈希算法的準則
- 安全性優先:避免 MD5、SHA-1,選擇 SHA-256 或 SHA-3。
- 性能權衡:BLAKE2 適合需要高性能的場景。
- 場景適配:密碼存儲需加鹽,區塊鏈需抗碰撞。
(3)、典型應用案例
- 區塊鏈:每個區塊的哈希值串聯形成不可篡改的鏈。
- HTTPS:證書簽名使用哈希算法確保來源可信。
- 分布式系統:一致性哈希優化節點數據分布。
逆風翻盤,Dare To Be!!!