SHA 家族完整指南:SHA-1、SHA-256、SHA-3 的差異與選擇

當你在瀏覽器網址列看到 HTTPS 的鎖頭圖示、在 Git 儲存庫看到那串 40 個字元的 commit hash、或在下載頁面看到「SHA-256 checksum」——這些背後都有 SHA 家族的身影。SHA(Secure Hash Algorithm)是目前最主流的密碼雜湊標準,但它不是一個演算法,而是一個演算法家族。理解各版本的差異,是每位開發者必備的基礎知識。

1. SHA 的由來

SHA 由美國國家安全局(NSA)設計,並由美國國家標準與技術研究院(NIST)發布為聯邦資訊處理標準(FIPS)。它的發展歷程如下:

  • 1993 年:SHA-0 發布,但因設計缺陷迅速撤回
  • 1995 年:SHA-1 發布,修正 SHA-0 的問題,輸出 160 位元
  • 2001 年:SHA-2 家族發布(SHA-256、SHA-512 等)
  • 2015 年:SHA-3(Keccak)正式成為 FIPS 202 標準,作為 SHA-2 的替代方案
SHA ≠ 加密
和 MD5 一樣,SHA 是單向雜湊函數,不是加密演算法。無法從 SHA 雜湊值反推原始資料,也沒有「解密」這個概念。

2. SHA-1:已走入歷史

SHA-1 曾是網路安全的基石,廣泛用於 SSL/TLS 憑證、程式碼簽章與版本控制系統。它將任意長度的資料轉換成 160 位元(40 個十六進位字元)的摘要。

2.1 為什麼 SHA-1 已不安全?

2017 年,Google 與 CWI 阿姆斯特丹研究院聯合公布了「SHAttered」攻擊:他們成功製造出兩份內容不同、但 SHA-1 完全相同的 PDF 檔案。這是密碼學史上第一個實際可行的 SHA-1 碰撞攻擊,計算量約需 6,500 CPU 年或 110 GPU 年。

此後,主要瀏覽器、CA(憑證授權機構)和 Git 都宣布棄用 SHA-1。GitHub 在 2023 年完全遷移至 SHA-256。

2.2 SHA-1 的遺留問題

儘管如此,SHA-1 在一些非安全性場景仍在使用:舊版 Git commit hash、某些嵌入式系統的韌體驗證等。這些場景需要逐步遷移至 SHA-256。

3. SHA-2 家族:現代標準

SHA-2 是一個演算法家族,包含六個成員,以輸出長度命名:

名稱輸出長度內部狀態主要用途
SHA-224224 bit256 bitSHA-256 的截斷版,較少使用
SHA-256256 bit256 bitTLS、程式碼簽章、Bitcoin、一般安全用途
SHA-384384 bit512 bitSHA-512 的截斷版,TLS 1.2 套件
SHA-512512 bit512 bit高安全性需求、64 位元平台效能更佳
SHA-512/224224 bit512 bit需要 224 位元輸出但使用 64 位元運算
SHA-512/256256 bit512 bit在 64 位元平台比 SHA-256 更快

3.1 SHA-256 為何最普及?

SHA-256 是目前使用最廣泛的 SHA-2 成員,原因如下:

  • 安全邊際充足:256 位元輸出對暴力破解提供 128 位元的安全邊際(生日攻擊需 2¹²⁸ 次操作)
  • 硬體加速支援:現代 x86(Intel SHA Extensions)與 ARM(ARMv8 Cryptography Extensions)均有 SHA-256 硬體指令
  • 廣泛的生態系支援:所有主流語言標準庫、TLS 套件、程式碼簽章規範均支援
  • 32 位元友善:SHA-256 基於 32 位元運算,在 32 位元平台比 SHA-512 更快

3.2 SHA-2 的設計原理

SHA-2 採用 Merkle–Damgård 結構:將訊息分成固定大小的區塊(SHA-256 為 512 位元),依序通過壓縮函數處理,最終輸出雜湊值。這與 MD5 和 SHA-1 的結構相同,也因此繼承了相同類型的潛在弱點(如長度延伸攻擊),但 SHA-256 的安全邊際目前仍足以抵禦已知攻擊。

4. SHA-3:全新的設計哲學

SHA-3 並非 SHA-2 的改版,而是採用完全不同架構的新演算法。它的前身是 Keccak,由 Bertoni、Daemen、Peeters 和 Van Assche 設計,在 2012 年 NIST 的公開競賽中脫穎而出。

4.1 海綿結構(Sponge Construction)

SHA-3 採用「海綿結構」,分為兩個階段:

  1. 吸收(Absorb):將訊息分塊「吸入」內部狀態(1600 位元的排列矩陣)
  2. 擠壓(Squeeze):從內部狀態「擠出」所需長度的輸出

這個設計天生免疫長度延伸攻擊,因為輸出前內部狀態有一部分是隱藏的。相較之下,SHA-256 如果不用 HMAC 包裝,就容易受到長度延伸攻擊。

4.2 SHA-3 的成員

  • SHA3-224、SHA3-256、SHA3-384、SHA3-512:固定輸出長度,與 SHA-2 同名成員對應
  • SHAKE128、SHAKE256:可擴展輸出函數(XOF),輸出長度可任意指定

4.3 SHA-3 比 SHA-2 更好嗎?

不一定。SHA-3 提供了設計多元性(不依賴同一種結構),在某些特定需求下更優秀:

  • 需要抵抗長度延伸攻擊且不想用 HMAC
  • 需要可變長度輸出(SHAKE)
  • 合規要求指定使用 SHA-3

但 SHA-256 在大多數場景下仍是首選,因為它的硬體加速支援更完善,生態系也更成熟。

5. SHA 家族完整比較

演算法輸出長度安全性速度(軟體)推薦場景
SHA-1 160 bit 已破解(SHAttered 2017) 不建議新系統使用
SHA-256 256 bit 安全(目前無已知碰撞) 中等(有硬體加速) TLS、憑證、程式碼簽章、一般用途
SHA-512 512 bit 安全(更高邊際) 在 64 位元平台快於 SHA-256 高安全性需求、64 位元系統
SHA3-256 256 bit 安全(不同設計) 較慢(硬體加速較少) 需要設計多樣性、抵抗長度延伸攻擊
SHAKE256 可變 安全 較慢 需要任意長度輸出的場景

6. 場景選擇指南

6.1 ✅ TLS/HTTPS 憑證 → SHA-256

所有現代 TLS 憑證均使用 SHA-256 簽章。SHA-384 用於更高安全等級的 EV 憑證。絕對不使用 SHA-1(瀏覽器會顯示警告或拒絕)。

6.2 ✅ 程式碼簽章與軟體發佈 → SHA-256

Windows Authenticode、macOS 程式碼簽章、APK 簽章均使用 SHA-256。發佈軟體時應同時提供 SHA-256 校驗碼讓使用者驗證。

6.3 ✅ 版本控制(Git)→ SHA-256(遷移中)

Git 傳統上使用 SHA-1,但 Git 2.29 起支援 SHA-256 模式。GitHub 和主要平台仍以 SHA-1 為主,但長期趨勢是遷移至 SHA-256。

6.4 ✅ 資料完整性驗證(非密碼)→ SHA-256

驗證檔案下載完整性、資料庫備份一致性等非惡意攻擊場景,SHA-256 是最佳選擇(比 MD5 更安全,比 SHA-512 更快)。

6.5 ❌ 密碼儲存 → 不要用任何 SHA

SHA 速度太快,不適合密碼儲存。請使用 bcrypt、Argon2 或 scrypt——它們的慢速特性才能有效抵抗暴力破解。

6.6 ✅ 需要訊息認證碼(MAC)→ HMAC-SHA256

若要對 SHA-256 加上金鑰驗證(防止偽造),應使用 HMAC-SHA256 而非裸 SHA-256,以防範長度延伸攻擊。

7. 計算範例

# 命令列(Linux/macOS)
sha256sum file.txt        # Linux
shasum -a 256 file.txt    # macOS
sha512sum file.txt        # SHA-512

# PHP
hash('sha256', 'hello')   // 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
hash('sha512', 'hello')

# Python
import hashlib
hashlib.sha256(b'hello').hexdigest()
hashlib.sha3_256(b'hello').hexdigest()  # SHA-3

# JavaScript(Node.js)
const crypto = require('crypto')
crypto.createHash('sha256').update('hello').digest('hex')
crypto.createHash('sha3-256').update('hello').digest('hex')

8. 常見問題

8.1 SHA-256 和 SHA-512 哪個更安全?

理論上 SHA-512 的安全邊際更高,但對大多數應用來說,SHA-256 的 128 位元碰撞抵抗力已綽綽有餘。選擇 SHA-512 的主要理由是在 64 位元平台上的效能(而非安全性需求)。

8.2 SHA-3 會取代 SHA-2 嗎?

短期內不會。SHA-2 目前沒有已知的安全漏洞,SHA-3 的主要價值在於提供設計多樣性——萬一未來 SHA-2 被攻破,SHA-3(採用完全不同的數學結構)仍然安全。NIST 建議兩者並存,而非取代。

8.3 為什麼 Git 還在用 SHA-1?

Git 使用 SHA-1 的原因是歷史遺留問題——它的物件模型深度依賴 40 字元的 SHA-1 hash。雖然已有 SHAttered 攻擊,但 Git 已加入緩解措施(檢測碰撞),且攻擊者仍難以在 Git 的使用情境中偽造 commit。遷移至 SHA-256 是長期方向,但需要整個生態系協調配合。

8.4 HMAC-SHA256 與 SHA-256 有什麼不同?

SHA-256 是單純的雜湊函數,任何人都能計算。HMAC-SHA256 是帶金鑰的訊息認證碼(MAC)——只有知道金鑰的人才能計算或驗證,常用於 API 簽名、JWT 和 webhook 驗證。

9. 小結

SHA 家族從 SHA-1 到 SHA-3 的演進,反映了密碼學研究的持續進步:SHA-1 已因碰撞攻擊走入歷史;SHA-256 是現代安全基礎設施的核心,幾乎所有場景的首選;SHA-512 在高安全需求或 64 位元平台有其優勢;SHA-3 以全新的海綿結構提供了設計多樣性。掌握這些差異,能讓你在系統設計、安全審查和技術選型時做出更準確的判斷。