如何計算 HMAC 簽章
用共用密鑰簽署 API 請求、除錯 Webhook 酬載,並以正確的 HMAC 演算法與摘要格式驗證 Stripe/GitHub/AWS 風格的簽章。

為什麼重要
Webhook 是雲端回呼你的方式。Stripe 在款項入帳時打你的伺服器;GitHub 在 release 建立時通知。為了證明訊息真偽,傳送端會用共用密鑰對 body 計算 HMAC 簽章。若你的驗證器一直不接受簽章,你無法判斷是密鑰錯、演算法錯,還是 body 被代理改過。能並排預覽輸入的 HMAC 工具,可把除錯週期從幾小時縮到幾分鐘。
三個實際場景
貼上酬載、密鑰與時間戳;計算 HMAC-SHA-256;與 Stripe-Signature 標頭比對。
Webhook 處理程式可上線
組出 canonical 字串,用共用密鑰 HMAC 簽署,放在標頭裡。
API 呼叫被接受
用廠商範例輸入計算、比對。對不上表示廠商文件有誤。
確認文件正確
操作說明
開啟 HMAC 產生器。
貼上訊息
被簽署的精確位元組——通常是原始 HTTP body。注意空白差異。
貼上密鑰
字串預設以 UTF-8 解讀。若廠商給的是二進位鑰,可切換「密鑰為 hex」或「密鑰為 Base64」。
選雜湊演算法
SHA-256 是現代預設;SHA-1 仍出現在舊系統;SHA-512 較少用但有支援。
選輸出格式
Hex(小寫)最常見。Base64 是 AWS Sig V4 等少數 API 所需。
與收到的簽章比對
貼上標頭裡的值。工具會逐字元標示相符與不符。
輸入
Message: t=1731234567.{"id":"evt_123","type":"payment_intent.succeeded"}
Secret: whsec_abc123xyz
Algorithm: SHA-256HMAC-SHA-256 hex
4ed7a40c1e1f9c0bba9d7c1f24eb44a3f0bd06d0c81bd5d4a7f6cf52a6f00f1e
實用技巧
- 先對 body 做 diff。 許多 webhook 失敗來自代理在 body 尾端加了換行。簽章針對精確位元組——多一個尾端換行就差很多。
- 伺服器端務必用常數時間比對。 那是你程式碼的責任,不是簽章工具的。瀏覽器工具可做明文比對,因為沒有資料離開頁面。
- 無停卻輪換密鑰可短暫接受兩把有效鑰。用工具分別算出兩個簽章,確認新鑰可用再汰換舊鑰。
- 把 canonical 字串寫進文件。 AWS Sig V4 等需依特定方式串 method、path、標頭與 body 雜湊;用手動方式在此工具重現一次以確認公式。
常見陷阱
常見陷阱
差一個尾端換行
IDE 裡的 body 有最後 \n,線上傳輸的沒有。簽章前要去除空白——但要與驗證端完全一致地處理。
常見陷阱
密鑰被當成錯誤編碼
有些廠商用 Base64 字串傳鑰;HMAC 要用解碼後的位元組,不是 ASCII 字元。依文件切換輸入編碼。
常見陷阱
訊息裡藏 UTF-8 BOM
開頭 EF BB BF 會改變雜湊。若簽章總差一大截,用 hex 檢視器打開來源。
何時不適合用這套
- 公開金鑰簽章(RSA、ECDSA、Ed25519)——需要不同驗證流程。見 如何線上驗證數位簽章。
- 對稱加解密——HMAC 只做認證,不加密。要機密性與真實性並存請用 AES-GCM。
- 密碼儲存——絕不要用 HMAC 存密碼。應用慢速 KDF。
FAQ
若鑰比區塊長度短呢?
HMAC 內部會處理。不必自行補位。
應在 JSON 排版前還是後簽章?
務必在 canonical 形式固定之後再簽。排版後再簽會壞掉。
有資料送到伺服器嗎?
沒有。HMAC 在瀏覽器以 WebCrypto 計算。