HMAC(雜湊訊息鑑別碼,Hash-based Message Authentication Code)是一種固定長度的密碼學標籤,透過將一組秘密金鑰與雜湊函式結合,針對訊息的精確位元組序列計算產生——最常使用的雜湊函式為 SHA-256、SHA-384 或 SHA-512。輸出結果的長度為 256、384 或 512 位元,視所選擇的 SHA-2 變體而定;接收端可藉此驗證訊息是由知道金鑰的一方所撰寫,且在傳輸過程中未遭竄改。產生 HMAC 的步驟包括:選擇 SHA-2 變體、以精確的位元組形式提供金鑰與訊息,並依目的通訊協定所要求的格式(十六進位或 Base64)複製所產生的標籤。
大多數在搜尋引擎輸入「how to generate HMAC」的使用者,通常是在執行下列三種工作之一:為送出的 API 請求簽章、檢查已收到的簽章格式,或是為支付或訊息服務商建立 webhook 驗證機制。這三種工作的作法相同,而取得精確且符合協定格式標籤的最快方式,就是使用 HMAC Generator,它完全在瀏覽器中執行,並且金鑰與訊息皆可接受 UTF-8 文字或原始十六進位位元組。接下來的章節將說明 HMAC 究竟是什麼、它在各種編碼方式中的定位,以及如何用三個簡單步驟產生正確的標籤。

HMAC 是什麼以及何時使用
HMAC 定義於 RFC 2104,並在 RFC 4868 中針對 SHA-2 加以形式化。其內部會對所選的雜湊函式執行兩次——一次作用於由金鑰衍生的內部填充(inner pad),另一次作用於包裹訊息摘要的外部填充(outer pad)——這也是為何只要底層雜湊函式具備抗碰撞性,此建構方式便視為安全。HMAC-SHA-1(HMAC-SHA-1)仍廣泛部署於舊版 API,例如較舊的 AWS 簽章與 OAuth 1.0a 流程,但新的設計應從 SHA-2 系列變體中擇一使用。
此標籤具有確定性:相同的金鑰與相同的訊息位元組永遠會產生相同的標籤。正是這個特性讓 HMAC 適用於以下情境:
- API 請求簽章——包括 AWS Signature Version 4、Stripe webhooks、Slack 簽章密鑰,以及許多自訂的 REST API。
- Webhook 驗證——傳送端在標頭中附上 HMAC 標籤,接收端則使用共享密鑰重新計算該標籤。
- 通訊協定中的訊息鑑別——TLS 匯出器、使用 HS256/HS384/HS512 簽署的 JWT,以及 IPsec ESP 皆在底層使用 HMAC。
- 檔案或韌體完整性檢查——適用於雙方已透過帶外(out-of-band)方式共享金鑰的情境。
HMAC 並非用於密碼雜湊。密碼驗證機制必須刻意設計得緩慢並加入鹽值;而 HMAC 標籤在設計上就是快速的。針對密碼,請使用記憶體密集型的 KDF,例如 Argon2id、scrypt、bcrypt 或 PBKDF2。How to Generate a Password Hash the Easy Way 指南將另行介紹該工作流程。
在 HMAC-SHA-256、SHA-384 與 SHA-512 之間擇一使用
這三種 SHA-2 變體僅在輸出長度與內部壓縮回合數上有所不同。實務上,選擇通常取決於接收端的通訊協定,而非效能,因為三者皆在現代硬體上執行得非常快速。
| 變體 | 輸出長度 | 常見使用情境 |
|---|---|---|
| HMAC-SHA-256 | 256 位元(32 位元組,64 個十六進位字元) | JWT HS256、Stripe webhooks、AWS SigV4(衍生)、多數現代 REST API |
| HMAC-SHA-384 | 384 位元(48 位元組,96 個十六進位字元) | 偏好 SHA-384 的 TLS 1.2 加密套件、部分政府與金融整合 |
| HMAC-SHA-512 | 512 位元(64 位元組,128 個十六進位字元) | JWT HS512、高度保證的整合、SHA-512 已受硬體加速的環境 |
若 API 說明文件指出「以 HMAC-SHA-256 簽章」,或顯示的範例標籤為 64 個十六進位字元,請選擇 HMAC-SHA-256。若註明 HS512 或顯示 128 個十六進位字元,則選擇 HMAC-SHA-512。HMAC Generator 可讓您在三種演算法之間切換而無需重新輸入內容——當規格不明確、且您想查看哪種輸出符合預期範例時,這項功能相當實用。
金鑰與訊息的編碼方式:UTF-8 與十六進位
HMAC 標籤結果「錯誤」最常見的原因,在於金鑰或訊息的位元組與伺服器所雜湊的內容不符。一段看似可列印的字串未必是 UTF-8——它可能包含不可見字元、雜訊換行符號,或會改變位元組序列的非 ASCII 碼點。像 0a1b2c3d 這樣的十六進位金鑰,也與 ASCII 字元 "0a1b2c3d" 並不相同。
HMAC Generator 會分別處理金鑰與訊息。每個欄位皆可在兩種模式間切換:
- UTF-8——該欄位會以標準 UTF-8 位元組進行編碼。當說明文件指出「密鑰為字串 abc123」,或從組態畫面複製值時,請使用此模式。
- 十六進位——該欄位會被解析為原始的十六進位位元組。當說明文件顯示如
4b 65 79 21的位元組、密鑰由 HSM 所產生,或從十六進位傾印中複製金鑰時,請使用此模式。
輸入十六進位時,請以連續字串形式鍵入各個位元組,必要時可加入空格——例如 4b 65 79 21 或 4b657921。此工具會驗證輸入內容,並回報任何奇數長度或非十六進位字元,而不會靜默替換為替代字元。若需先檢查或轉換原始位元組,Hex to Text Converter 與 UTF-8 Encoder / Decoder 可在不進行任何上傳的情況下完成轉換。
如何逐步產生 HMAC
- 開啟 HMAC Generator,並選擇與接收端通訊協定相符的演算法——SHA-256、SHA-384 或 SHA-512。預設值為 HMAC-SHA-256,這是現代 REST API 最常見的選擇。
- 選擇金鑰的編碼方式——若密鑰為人類可讀的文字,請選 UTF-8;若密鑰以原始位元組形式發布,則選 Hex。請輸入精確的值,且開頭與結尾不得包含空白字元;隱藏的換行字元將會改變標籤。
- 分別選擇訊息的編碼方式。多數 API 會對一條標準化字串(例如
timestamp + "." + body)進行簽章,因此請將該組合後的字串以 UTF-8 形式貼上。 - 產生標籤並檢查長度——64、96 或 128 個十六進位字元。若與說明文件中的預期範例不符,請在質疑工具前,再次確認演算法與位元組編碼設定。
- 以要求的格式複製標籤——若用於 Stripe 的
Stripe-Signature等標頭內文,請使用十六進位;若通訊協定將標籤包裝為 JWT 風格的簽章,則使用標準 Base64。除非規格明確允許,否則請勿截斷。
若輸出結果必須嵌入 JSON 或 URL 查詢字串中,Base64 標籤可能需要額外的編碼。針對 URL 安全情境,URL Decoder 可在不遺失底層值的情況下處理百分比編碼。若是為了內部完整性檢查而非遠端簽章,且該通訊協定不需要密碼學強度時,Checksum Calculator 可涵蓋較輕量的 XOR-8 與 Modbus LRC 數值。
讀取輸出結果與常見陷阱
十六進位輸出依照慣例使用小寫 a–f,且以位元組對齊——HMAC-SHA-256 為 64 個字元、HMAC-SHA-384 為 96 個、HMAC-SHA-512 為 128 個。Base64 輸出遵循 RFC 4648 並含填補字元,因此結尾會有一或兩個 = 字元;若接收端回應「invalid base64」,最可能的原因為缺少填補字元,或使用了錯誤的字母表(URL 安全版與標準版)。
幾乎所有「我的 HMAC 對不上」的回報,皆可歸咎於以下三項錯誤:
- 多餘的空白字元——金鑰或訊息中包含結尾空格、定位字元,或最末的換行符號。若差異持續存在,請使用十六進位檢視器確認位元組數量。
- 十六進位大小寫錯誤——大多數驗證端接受大寫或小寫,但少數自訂實作會逐位元組比對。請讓輸出與工具所產生的形式完全一致。
- 編碼方式不一致——伺服器將密鑰視為 ASCII,而用戶端將其視為 UTF-8,或反之亦然。解決方法為與伺服器說明文件所記載的位元組解讀方式保持一致。
若完成上述檢查後標籤仍不相符,請以相同的演算法對已知輸入重新產生——例如金鑰 key 與訊息 The quick brown fox jumps over the lazy dog 會產生一個固定的 HMAC-SHA-256 值,便於查驗。若該已知輸入亦失敗,幾乎可以確定問題出在金鑰編碼。
HMAC、純雜湊與認證加密
純粹的 SHA-256 摘要——例如透過 SHA256 Hash Generator 這類工具所產生——僅能確認訊息未遭變更,但無法證明撰寫者是誰,因為任何人都能重新計算一個純雜湊值。HMAC 加入了秘密金鑰,因此僅有持有金鑰的一方才能產生出有效的標籤。這也是為何基於權杖的 API 幾乎皆採用 HMAC 而非裸 SHA-256。
若需在單一操作中同時達到機密性與鑑別,認證加密(如 AES-256-GCM)為標準工具。AES Encryption Online 頁面涵蓋該工作流程,適用於需求為保護訊息本身而非僅對其簽章的情境。針對由密碼衍生的金鑰,Password Generator 可產生高熵值的秘密以供 HMAC 使用,而 Password Strength Checker 則在您將金鑰投入正式環境前,針對長度與明顯模式提供透明的回饋。