雜湊與 HMAC 產生器

MD5不安全
SHA-1不安全
SHA-256
SHA-512

MD5 與 SHA-1 已被破解,不可用於密碼或簽章。用於校驗碼與快取鍵則仍然適用。

您輸入的內容不會被儲存、記錄或分享。

輸入或貼上文字,即可同時取得 MD5、SHA-1、SHA-256 與 SHA-512 雜湊值,也可切換至 HMAC 使用密鑰簽章。所有運算都在瀏覽器中完成,文字與密鑰都不會離開您的裝置。

使用方式

  1. 將文字貼到輸入框。
  2. 輸入時會即時計算四種雜湊值。
  3. 使用旁邊的按鈕複製任一雜湊值。

雜湊能保證什麼

密碼學雜湊函式會把任意長度的輸入,確定性地對應到固定長度的摘要:相同的位元組永遠得到相同結果,而改變一個位元,大約會改變一半的輸出。讓它有用的特性有三個,不同用途需要的特性也不同。

抗原像性指的是給定一個摘要,無法找到能產生它的輸入。抗第二原像性指的是給定一個輸入,無法找到另一個具有相同摘要的輸入。抗碰撞性指的是無法找到任何一對發生碰撞的輸入;這是三者中最容易被攻擊的,因為攻擊者可以自己選擇兩邊的輸入。

最後這個差異,正是為什麼一個被攻破的演算法並非在所有用途上都同樣危險。MD5 碰撞幾秒內就能產生,但沒有人能反推 MD5 摘要,所以把 MD5 用作快取鍵或非對抗情境的校驗碼沒有問題,用作簽章則不行。

各演算法的現況

MD5 自 2004 年起就被視為已攻破,而選擇前綴碰撞,也就是攻擊者製作兩份內容意義不同卻雜湊相同的文件,如今成本已經很低。它在 2008 年被用來偽造一個可運作的憑證機構,2012 年也被 Flame 惡意軟體利用。可以用在校驗碼、ETag 與快取鍵;絕不要用在任何攻擊者能從破壞中獲利的地方。

SHA-1 隨後也淪陷。第一個實際碰撞在 2017 年以兩份 PDF 展示,2020 年又以數萬美元的成本實現了選擇前綴碰撞。瀏覽器多年前就已停止接受 SHA-1 憑證,Git 也一直在逐步淘汰它。請把它當作壽命比較長的 MD5。

SHA-256 與 SHA-512 是目前的預設選擇,沒有已知的實際弱點。兩者同屬 SHA-2 家族;儘管輸出較長,SHA-512 在 64 位元硬體上往往更快。SHA-3 的定位是結構不同的備援,而非取代品;在大型檔案速度很重要的場合,BLAKE3 也值得了解。

HMAC,以及為什麼不能直接把金鑰和訊息一起雜湊

單純的雜湊無法證明是誰產生的,因為任何人都能計算。HMAC 加入了秘密金鑰,所以摘要相符就代表傳送者知道金鑰,而且訊息未被竄改。Stripe、GitHub 等各家服務的 Webhook 簽章,以及 AWS API 請求的驗證,都是靠它。

直覺的做法,也就是把金鑰接在訊息前面一起雜湊,對 SHA-2 家族來說並不安全,因為它們屬於 Merkle-Damgård 結構,摘要就是整個內部狀態。取得一個有效摘要的攻擊者,可以從該狀態繼續運算並附加資料,在完全不知道金鑰的情況下,產生更長訊息的有效摘要。HMAC 以兩把衍生金鑰雜湊兩次的巢狀結構,正是用來防止這種攻擊。

驗證時有一點一定要做對:用固定時間比較摘要。一般的字串比較一發現不同就會立即返回,累積足夠多次請求後,時間差是可以量測的,攻擊者便能逐位元組還原簽章。大多數程式語言都有提供專門的函式來處理這件事。

雜湊不是加密,也不是密碼儲存

雜湊是單向的,而且沒有金鑰:沒有東西可以解密,也沒有辦法還原輸入。如果你需要取回資料,你要的是加密,那是完全不同的工具。

對密碼來說,快速雜湊恰恰是錯誤的選擇。速度是攻擊者的優勢:一般消費級硬體每秒就能對外洩的資料庫嘗試數十億次 SHA-256 猜測,而沒有加鹽的摘要更能直接用預先計算好的表查出來。密碼儲存需要刻意設計得緩慢、消耗大量記憶體的函式,並為每個密碼加上獨立的鹽,例如 bcrypt、scrypt,或目前推薦的 Argon2id。

還有一種較隱晦的誤用值得一提:對識別資訊做雜湊來「匿名化」。雜湊電子郵件地址或電話號碼什麼也保護不了,因為可能的輸入範圍小到可以全部列舉。任何拿到摘要的人,都能把手上所有的地址雜湊一遍再比對。低熵值的雜湊只是查詢鍵,不是匿名化。

一步步驗證下載的檔案

公開的校驗碼只回答一個問題:我收到的位元組,跟發布者手上的位元組是不是一樣。在本機對檔案計算雜湊——macOS 上用 shasum -a 256 file.iso、Linux 上用 sha256sum、PowerShell 裡用 Get-FileHash——再和下載頁面上的摘要比對。只要有一個字元不同,這就不是同一個檔案。

這個比對沒告訴你的,是發布者的網頁本身是不是真的。如果攻擊者能換掉下載檔案,通常也能換掉旁邊那串校驗碼;認真的專案之所以會用 GPG 金鑰為校驗碼檔案簽章,而不只是公布摘要,原因就在這裡。先驗證簽章、再驗證校驗碼,這一整條鏈才真正證明了什麼。

這也是為什麼在沒有攻擊者的情境下,MD5 當校驗碼仍然可以接受,當簽章卻不行。要對付傳輸損壞的下載,MD5 綽綽有餘;但面對一個刻意要讓兩個檔案得到相同摘要的人,它從 2004 年起就已經被攻破了。

雜湊不只是檢查,更是位址

現代基礎設施有很大一部分是用雜湊而不是用名稱來識別內容。Git 以內容的摘要為每個物件命名,這正是 commit 識別碼穩定、可察覺竄改、而且與儲存庫放在哪裡無關的原因。容器映像檔的 digest 運作方式相同,套件的 lock 檔也一樣,它們把相依套件釘在確切的位元組上,而不是釘在某個別人可以重新發布的版本號上。

去除重複用的是同一個想法:對每個區塊計算雜湊的備份系統,相同的區塊只會儲存一份;而內容傳遞網路可以直接用摘要當快取的鍵,完全不必擔心送出過期的資料,因為內容不同,位址就不同。

Merkle tree 把這個想法再往上延伸。把成對的雜湊一層層往上再做雜湊,最後會得到單一的根摘要,它承諾了整份資料集的內容;這讓用戶端不必下載全部資料,就能驗證某一筆項目確實屬於其中。憑證透明度紀錄、區塊鏈,以及好幾種複寫式資料庫,都倚賴這個結構。

正確驗證 webhook 簽章

這套做法在 Stripe、GitHub、Slack 以及大多數服務上都一樣:發送方用共享密鑰對原始的請求主體計算 HMAC,把摘要放進標頭;接收方重新計算一次再比對。實作是否牢靠,取決於四個細節。

第一,要對原始主體做雜湊,不要用解析完 JSON 再重新序列化的版本——鍵的順序和空白會改變位元組,也就改變了摘要。第二,比對要用常數時間,因為一般的字串比較會洩漏第一個相異之處在哪裡,請求數量夠多時,那個時間差就足以拼出簽章。第三,把發送方提供的時間戳記納入簽章的內容,並拒絕超過幾分鐘的請求,否則被攔截下來的請求可以被無限次重放。

第四,同時支援兩把密鑰。如果接收方只知道一把,密鑰輪替根本不可能;常見做法是在一段短暫的重疊期間內同時接受兩者。

為密碼雜湊挑選參數

目前的建議是 Argon2id,和單純的雜湊不同,它需要參數:記憶體、迭代次數與平行度。真正能擊退專用硬體的是記憶體成本,因為 GPU 和 ASIC 的運算能力遠遠超過它們每個核心所能取用的高速記憶體。常見的起點是 19 MiB 搭配兩次迭代,硬體條件允許時就再往上調。

調校的方式是實測。在實際要執行它的機器上量測,選出能讓一次登入維持在大約四分之一秒以內的最高成本;同時記得,登入尖峰會讓這個成本乘上同時湧入的每一個請求。工作因子設為 12 的 bcrypt 仍然可以接受,而且在某些技術堆疊上更容易部署;scrypt 則介於兩者之間。

遷移不需要任何人的密碼。把演算法和參數跟著每一筆摘要一起存起來,驗證時照著儲存的紀錄所寫的方式進行,並在登入成功的當下用新設定重新計算雜湊。幾個月下來,大多數活躍帳號就會自己完成遷移。

什麼時候雜湊是錯的工具

把識別資料雜湊起來當作匿名化並不管用,而這背後的理由值得理解,而不是死背。雜湊是決定性的,而輸入的空間很小:電子郵件地址和電話號碼就那麼多種,所以任何拿到這些摘要的人,都可以把手上的每一個候選值都雜湊一遍再逐一比對。好幾種標榜保護隱私的廣告與分析方案,正是建立在這個錯誤之上。

如果你真的需要在不揭露識別資料的情況下比對它們,該用的是另一類密碼學工具——使用只有你握有、別人拿不到的密鑰的 keyed hash,或是專為 private set intersection 設計的協定。

另外兩種誤用也很常見。雜湊不是壓縮演算法,因為你沒辦法從它還原出任何東西。而 CRC32 或 MurmurHash 這類非密碼學雜湊,用在雜湊表和校驗碼上很出色,一旦輸入是由攻擊者挑選的就毫無用處,因為對方可以刻意製造碰撞,把一個資料結構退化成線性掃描。

常見問題

HMAC 是什麼?什麼時候需要用?
HMAC 結合雜湊與密鑰,用來證明訊息來自持有該密鑰的人且未被竄改。單純的雜湊無法證明這兩點,因為任何人都能重新計算。Webhook 內容與 API 請求的簽章都使用 HMAC。切換到 HMAC 模式並輸入密鑰即可。
MD5 可以安全使用嗎?
不可用於安全用途。MD5 已有實際可行的碰撞攻擊,絕不可用於密碼、簽章,或防範有意攻擊者的完整性驗證。但用於校驗碼、快取鍵與 ETag 等非對抗性場景仍然合理,因此本工具仍提供。
那密碼應該怎麼雜湊?
不要使用這裡的任何一種。密碼儲存需要專為此設計、刻意緩慢且加鹽的演算法,例如 bcrypt、scrypt 或 Argon2。像 SHA-256 這類快速通用雜湊每秒可被暴力嘗試數十億次。
我的輸入會傳送到伺服器嗎?
不會。SHA 系列使用瀏覽器的 Web Crypto API,MD5 則以頁面內的 JavaScript 實作,文字不會離開您的裝置。
為什麼 Web Crypto API 沒有 MD5?
因為 MD5 在密碼學上已被破解,所以規格刻意排除。本工具另行實作,並以 RFC 1321 官方測試向量驗證正確性。
可以處理中文嗎?
可以。雜湊前會先編碼為 UTF-8,因此中文、日文、韓文與表情符號都會得到與標準命令列工具相同的結果。

最後更新:

回報問題

請提供操作步驟、預期結果及實際結果。請移除機密與個人資料。

相關工具