當你在瀏覽器網址列看到 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 的替代方案
和 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-224 | 224 bit | 256 bit | SHA-256 的截斷版,較少使用 |
| SHA-256 | 256 bit | 256 bit | TLS、程式碼簽章、Bitcoin、一般安全用途 |
| SHA-384 | 384 bit | 512 bit | SHA-512 的截斷版,TLS 1.2 套件 |
| SHA-512 | 512 bit | 512 bit | 高安全性需求、64 位元平台效能更佳 |
| SHA-512/224 | 224 bit | 512 bit | 需要 224 位元輸出但使用 64 位元運算 |
| SHA-512/256 | 256 bit | 512 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 採用「海綿結構」,分為兩個階段:
- 吸收(Absorb):將訊息分塊「吸入」內部狀態(1600 位元的排列矩陣)
- 擠壓(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 以全新的海綿結構提供了設計多樣性。掌握這些差異,能讓你在系統設計、安全審查和技術選型時做出更準確的判斷。