HMAC署名を計算する方法
共有鍵でAPIリクエストに署名する、ウェブフックペイロードをデバッグする、Stripe/GitHub/AWS流の署名をアルゴリズムとダイジェスト形式ごとに検証する方法。

なぜ重要か
クラウドの「折り返し」がウェブフックです。Stripeは決済確定時、GitHubはリリース時にサーバーへ叩きます。真正性は共有鍵でボディ全体をHMACした署名で証明されます。検証側がすべて弾いてしまうと、鍵間違い、アルゴリズム間違い、プロキシによるボディ改変のどれか切り分けができません。入力プレビュー付きのHMACツールがあれば、デバッグは数時間から数分へ短縮できます。
実際の3つのシーン
ペイロード・シークレット・タイムスタンプを貼り、HMAC-SHA-256を計算してStripe-Signatureヘッダーと比較します。
ハンドラをリリース
正準文字列を組み立て共有鍵でHMACし、ヘッダーに付けます。
APIが受理
ベンダー提供サンプルで計算し一致させます。不一致ならドキュメント側の誤りの可能性があります。
ドキュメントの是非を確認
手順
HMACジェネレーターを開きます。
メッセージを貼る
署名対象となった正確なバイト列—典型的には生のHTTPボディ。空白の差にも注意してください。
シークレット鍵を貼る
文字列は既定でUTF-8解釈。ベンダーがバイナリ鍵なら「secret is hex」「secret is Base64」を切り替えます。
ハッシュアルゴリズムを選ぶ
現代の既定はSHA-256です。SHA-1はレガシーに残り、SHA-512はまれですがサポートされます。
出力形式を選ぶ
ヘッダー値によくあるのは小文字hex。AWS Sig V4など一部はBase64必須です。
受信署名と突き合わせる
ヘッダーから値を貼り、ツールが文字単位で一致/不一致を強調します。
入力
Message: t=1731234567.{"id":"evt_123","type":"payment_intent.succeeded"}
Secret: whsec_abc123xyz
Algorithm: SHA-256HMAC-SHA-256 hex
4ed7a40c1e1f9c0bba9d7c1f24eb44a3f0bd06d0c81bd5d4a7f6cf52a6f00f1e
実践テクノ
- 署名の前にボディをdiff。 失敗の多くはプロキシが末尾改行を足すことです。署名はきっちりそのバイト列に対するものです—末尾
\n1つで変わります。 - サーバー側は常時等時間比較。 コードの責務でありツールの責務ではありません。ブラウザ側はページにデータが残らない前提で素の比較で構いません。
- ダウンタイムなしに鍵ローテ。 短期間だけ2鍵両方受理し、ツールで新鍵側の署名が合うことを確認してから旧鍵を廃止します。
- 正準文字列を文書化。 AWS Sig V4はメソッド・パス・ヘッダー・ボディハッシュなどを特定順で連結します。ツールで一度手組み検証すると式の誤りに気付けます。
よくある落とし穴
よくある誤り
末尾改行が1つズレている
IDE上のボディには最終\nがあるが送信時は無い等。検証側が除去するものと正確に揃えてから署名します。
よくある誤り
鍵エンコードの解釈ミス
ベンダーがBase64で鍵配布することがあります。デコード済みバイトでHMACすべきところをASCIIとして扱っている典型です。ドキュメントに合わせ入力エンコードをトグルしてください。
よくある誤り
ペイロード先頭にUTF-8 BOM
先頭バイト列EF BB BFが混入するとハッシュが変わります。署名が原因不明にズレ続けるときはソースをhex表示で確認します。
向いていない用途
- 公開鍵署名(RSA、ECDSA、Ed25519)—別検証です。オンラインでデジタル署名を検証するを参照。
- 対称暗号化—HMACは認証のみで机密性はありません。機密+真正性にはAES-GCMなど。
- パスワードハッシュ—HMACでのパスワード保存は避けます。低速KDFを。
FAQ
鍵がブロックサイズより短い場合は?
HMACが内部的に処理します。手でパディングする必要はありません。
JSON整形の前後どちらで署名?
正準形が固定されたあとに署名します。整形し直すと署名は壊れます。
サーバーへ何か送られますか?
いいえ。WebCryptoによりブラウザ内で計算されます。
次のステップ
- プロトコルが先に
body_hashその後HMACを求めるなら、ハッシュジェネレーターでボディのみ先に計算します。 - 完全リクエスト署名にはパラメータ署名。
- JWTのHS系はHMACです—補助としてエンコード/デコードでJWTセグメントを見ます。