一個 HMAC 產生器範例會顯示三個輸入項目——雜湊選擇、共用密鑰、以及訊息——以及以十六進位和標準 Base64 兩種格式呈現的加密雜湊標籤,因此持有相同金鑰的兩個系統可以透過重新計算相同的位元組來確認訊息的真實性。標籤本身並未加密;它是一個固定長度的指紋,只有知道精確金鑰的一方才能產生。HMAC-SHA256 會產生 32 位元組,HMAC-SHA384 會產生 48 位元組,而 HMAC-SHA512 會產生 64 位元組,且所選的雜湊演算法永遠決定標籤的長度。位元組的一致性是整個機制的核心:驗證方必須看到相同的金鑰位元組、相同的訊息位元組,以及相同的演算法,否則重新計算出的標籤將不會相符。由於十六進位和 Base64 只是相同位元組的不同呈現方式,編碼上的差異看似是不同的值,實際上解碼後仍是同一個標籤。了解一個範例能展示什麼、無法展示什麼,是正常運作的整合與耗時除錯之間的差別。

一個真實的 HMAC 產生器範例包含哪些內容
一個妥善呈現的 HMAC 產生器範例,內容不僅僅是一段輸出字串。它會將已知的金鑰搭配已知的訊息,標明所使用的雜湊演算法,並以下游通訊協定所要求的每種格式來顯示標籤。HMAC 產生器正好提供了這些功能:金鑰欄位、訊息欄位、各自獨立的 UTF-8 或十六進位切換選項、雜湊選擇器,以及同時以小寫十六進位和填充式 Base64 呈現的標籤。這三項設定各自獨立,任何一項的改變都可能翻轉輸出結果。一個有完整文件的範例會把這些設定清楚地展示出來。一旦你能看出使用了哪種雜湊、金鑰用了哪些位元組、訊息用了哪些位元組,你就能擁有所需的一切,在自己的伺服器上、使用自己的程式語言,或在工具本身內重現該標籤。
像 RFC 4231 這類文件,正是圍繞著這個概念建立其逐步演練範例。RFC 公布了精確的金鑰位元組、精確的訊息位元組,以及正確實作必須產生的精確標籤,讓實作人員能夠以已知答案進行測試。每當你看到一個已公布的 HMAC 值時,該值所處的脈絡其實也在扮演同樣的角色:它消除了輸入了哪些位元組、選擇了哪種演算法方面的模糊性。本站的這個工具鎖定了八個完整的 RFC 4231 一致性標籤,代表同樣的「精確位元組測試」概念已被內建在這個頁面中。
在範例中選擇 SHA-256、SHA-384 或 SHA-512
在執行範例之前,雜湊的選擇是由將驗證你標籤的通訊協定所決定的。SHA-256 是 webhook 簽章、JWT HS256 權杖,以及大多數公開 API 簽章機制中最常見的選擇。SHA-512 是在需要更大安全邊際時的預設選項,而 SHA-384 則偶爾會在需要中間值的情境中被指定。雜湊演算法並不會改變標籤的意義,但會改變其長度以及線上傳輸時的編碼方式。
| 雜湊 | 標籤長度(位元組) | 十六進位字元數 | Base64 字元數 | 典型用途 |
|---|---|---|---|---|
| HMAC-SHA256 | 32 | 64 | 44 | Webhook 簽章、JWT HS256 |
| HMAC-SHA384 | 48 | 96 | 64 | 部分 TLS 和 API 情境 |
| HMAC-SHA512 | 64 | 128 | 88 | 更高的安全邊際、AWS 風格的簽章 |
先選定雜湊演算法,再據此設計範例。HMAC 產生器讓你能在三種演算法間切換而無需重新輸入金鑰或訊息,因此你可以用同一個範例在每種演算法下執行,並一目了然地比較標籤長度。十六進位字元數永遠是位元組數的兩倍(每個十六進位字元對應一個 nibble),而填充式 Base64 的字元數永遠是 4 的倍數,因為編碼器會加入填充字元,讓輸出湊齊到下一個三位元組輸入群組的整數倍。
執行一個逐步演練的 HMAC-SHA256 範例
若要一個乾淨的逐步演練範例,可以使用 RFC 4231 的第一個測試向量,該向量記錄了正確的 HMAC-SHA256 實作所必須產生的精確金鑰位元組、訊息位元組,以及預期標籤。該向量長度短、規格完整,且被廣泛用作新 HMAC 實作的冒煙測試。
- 在你的瀏覽器中開啟 HMAC 產生器。
- 從演算法選擇器中選取 HMAC-SHA256 作為雜湊演算法。
- 將金鑰模式設為十六進位,並輸入 0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b。這是 20 個位元組的 0x0b,完全對應 RFC 4231 測試案例 1 的金鑰。
- 將訊息模式設為十六進位,並輸入 4869205468657265。這些是 ASCII 字串 "Hi There" 的 UTF-8 位元組。這裡選擇十六進位模式是正確的,因為 RFC 公布的是二進位輸入。
- 產生標籤。該工具會以小寫十六進位和標準填充式 Base64 兩種格式呈現完整的 32 位元組 HMAC-SHA256 結果。
- 將產生的十六進位標籤與 RFC 公布的數值進行比對:b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7。完全相符即代表該工具是使用與 RFC 相同的位元組進行計算。
- 將訊息模式切換為 UTF-8,並重新以文字方式輸入 "Hi There",以確認該工具對該欄位產生相同的標籤。金鑰(20 個位元組的 0x0b)無法以 UTF-8 文字重新輸入,因為 0x0b 並非可列印字元,所以十六進位模式仍是該金鑰的正確選擇。
這個相同的工作流程可以推廣到任何通訊協定:識別文件中記載的金鑰位元組、識別文件中記載的訊息位元組、選擇符合規格的編碼模式,然後將輸出與任何已公布的測試數值進行核對。HMAC 產生器正是圍繞著 RFC 4231 的向量所打造,因此新整合的首次執行就能在進入正式環境前進行交叉驗證。使用相同的 20 位元組 0x0b 金鑰和相同的 8 位元組 "Hi There" 訊息,在 SHA-384 或 SHA-512 下再執行一輪,即可看到標籤長度分別跳升至 96 或 128 個十六進位字元。
十六進位與 Base64:同一標籤的兩種視圖
一旦範例計算完成,相同的 32 位元組會以兩個方塊的形式出現在畫面上。十六進位方塊將每個位元組顯示為兩個小寫字元,SHA-256 共產生 64 個十六進位字元(32 位元組 × 每位元組 2 個十六進位字元 = 64)。Base64 方塊則以標準 RFC 4648 字元集加上填充方式顯示相同的位元組,共 44 個字元(編碼器以每三個位元組為一組輸入,每組輸出四個字元,最後一組再填充至 4 的倍數)。這兩個字串在視覺上不同,但解碼後是相同的位元組。
| 格式 | SHA-256 的長度 | 字元集 | 常見用途 | 解碼後是否為相同的標籤位元組 |
|---|---|---|---|---|
| 小寫十六進位 | 64 個字元 | 0-9, a-f | Webhook 標頭、除錯日誌、組態檔 | 是 |
| 標準填充式 Base64 | 44 個字元 | A-Z, a-z, 0-9, +, /, = | JSON 請求主體、HTTP 標頭、二進位安全欄位 | 是 |
| Base64url(無填充) | 43 個字元 | A-Z, a-z, 0-9, -, _ | JWT 簽章、URL 路徑與查詢元件 | 是,但需要字元替換 |
| 截斷式標籤 | 視情況而定 | 視通訊協定而定 | 僅在通訊協定明確要求時使用 | 僅在通訊協定定義如此規定時才成立 |
這是範例容易出錯的第二個地方。十六進位和 Base64 在傳輸過程中並不能互換,因為接收端系統可能只會解析其中一種格式,但它們代表的是同一個標籤。一個公布 Base64 範例的通訊協定,不會接受同一個欄位中的十六進位字串,即使其底層位元組完全相同。HMAC 產生器永遠會同時以兩種編碼輸出完整的標籤,因此只要接收端預期的是該種格式,該範例無論以何種形式引用皆可。若想更仔細地了解這兩種呈現方式在所有三種雜湊變體下的比較,HMAC-SHA256 標籤產生器:十六進位與 Base64 指南透過更多的輸入,以相同的比較方式進行了完整的逐步介紹。
為什麼重新計算的標籤與範例不符
即使使用相同的演算法,仍有四個常見的差異會導致輸出不同。第一個是金鑰位元組:UTF-8 中的 "secret" 金鑰是 6 個位元組(73 65 63 72 65 74),而對於純 ASCII 字元而言,UTF-8 編碼等於那些位元組值是定義使然,並非巧合。第二個是訊息編碼:UTF-8 中的 "Hi There" 字串是 48 69 20 54 68 65 72 65,但同一字串在 UTF-16LE 下則是不同的 16 位元組序列。第三個是空白字元:尾端的換行、前端的空格,或是 Windows 風格的 CRLF 而非 LF,都會改變訊息的位元組,進而改變標籤。第四個是輸出本身的編碼:該工具永遠輸出小寫十六進位和標準填充式 Base64,但驗證方可能預期的是 Base64url、可能在前面加上像 "SHA256=" 這樣的演算法識別字首,或可能要求將標籤截斷為固定長度。
除錯不符狀況的最快方法,是使用與失敗整合完全相同的條件,在 HMAC 產生器中重現該範例。強制讓金鑰模式和訊息模式符合規格,貼上那些位元組,並確認產生器的十六進位輸出與接收端計算出的結果相符。如果相符,問題就在接收端。如果不相符,問題就在金鑰或訊息是如何被輸入的。一個完整的 RFC 4231 向量,例如上述的 SHA-256 案例,是最可靠的起點,因為每一個位元組和預期輸出都有清楚記載且毫無歧義。
金鑰處理、位元組限制,以及通訊協定規則
只有在周邊的實作做法正確時,這個範例才能真正保護你。無論你複製哪個範例,以下幾項原則皆適用。使用獨立產生、符合該通訊協定所需的高熵金鑰材質,透過受保護的管道進行分發,依用途區分不同金鑰,並在懷疑遭到破解時立即更換。人類使用的密碼很少適合作為強健的 HMAC 金鑰;若必須將密碼轉為金鑰,應使用該通訊協定所要求的、以密碼為基礎的 KDF,並依照應用程式指定的精確參數執行,而不要自行變通。
此頁面將每個解碼欄位限制為 1,000,000 位元組,這對一般承載量已綽綽有餘,但無法取代串流處理。即使某些低階標準在技術上允許零長度輸入,介面仍會拒絕空的金鑰和空的訊息,因為一次意外的點擊絕不應產生一個可發佈的標籤。非同步作業會攜帶一個身分識別權杖,因此當 Web Crypto 仍在運作時變更輸入,可避免較舊的結果覆蓋新的狀態。該工具不會輸出 Base64url、不會在前面加上演算法識別字首,也不會將訊息與其標籤打包在一起。這些轉換各自都是通訊協定的工作,而正確的套用位置就是規格所指定之處。十六進位和 Base64 只是相同標籤位元組的不同呈現方式,將其中任何一種解碼回原始位元組,都會得到雜湊所產生的同一段 32、48 或 64 位元組序列。