Webhook 署名の生成と検証

元のボディと署名シークレットを貼り付けて HMAC 署名を生成または検証します。GitHub と Stripe の形式に対応し、一致してもタイムスタンプの新しさや再生は検査しません。

ブラウザ内でローカルに実行
署名の入力
貼り付けた改行はこの欄で LF に変換されます。CRLF バイトで署名されたボディを再現するにはオンにしてください。
生成された署名
Enter a secret and payload to generate a signature.
受信した署名を検証
署名を生成するか、受信した署名を貼り付けてローカルで検証します。
ヘッダープレビュー
Generate a signature to see the corresponding request header.
サーバーサイド検証パターン
Generate a signature to see Node.js and PHP verification patterns.

受信した正確なバイト列に署名する

Webhook の検証は、検証前にミドルウェアが本文をパースまたは再整形すると失敗します。生の本文を保持し、プロバイダーが文書化した署名入力を適用し、サーバーコードでタイミングセーフな比較を使用してください。このページはペイロードやシークレットをどこにも送信しません。

Webhook 署名の生成・検証の手順

貼り付けたボディをそのまま HMAC-SHA-256 / SHA-384 / SHA-512 で署名し、GitHub の X-Hub-Signature-256 と Stripe の v1 形式を再現して、受信した署名を同じシークレットでバイト単位に照合します。

計算はこのタブの Web Crypto で行います。ボディ、シークレット、署名はブラウザー内に留まり、一致が確認できるのはバイトであってイベントの新しさではありません。

  1. 署名形式を選びます。汎用 HMAC、GitHub X-Hub-Signature-256、Stripe v1 のいずれかです。プロバイダー形式は常に SHA-256 を使います。
  2. 元のボディをそのまま貼り付け、シークレットを入力します。Stripe では「現在時刻を使用」を押すか送信されたタイムスタンプを入力し、CRLF バイトで署名されている場合は「CRLF 改行で署名する」をオンにします。
  3. 署名を生成すると、対応するリクエストヘッダーと Node.js / PHP の検証例が表示されます。生成後に他の入力を変更すると、再生成するまで値が薄く表示されます。
  4. 受信した値を確認するには検証欄に貼り付けて検証します。16 進数はどの形式でも、base64 は汎用 Webhook で使えます。Stripe-Signature ヘッダーを丸ごと貼れば t= も読み取ります。
  5. 「署名をコピー」でヘッダー値を取得し、「クリア」ですべての欄を空にして汎用 HMAC に戻します。

生成される結果に含まれるもの

形式ごとの署名対象

汎用 HMAC は生のボディを署名します。GitHub は同じボディを署名し、X-Hub-Signature-256 に sha256=<16進> を送ります。Stripe は「<タイムスタンプ>.<ボディ>」を署名し、Stripe-Signature に t=<タイムスタンプ>,v1=<16進> を送ります。

Stripe のヘッダーを貼り付けた場合、署名対象に使うのはヘッダー内の t です。タイムスタンプ欄はヘッダーに t= がないときだけ参照します。シークレットのローテーションで v1 が複数ある場合は、どれか一致すれば検証成功です。

同じボディでも一致しない理由

テキスト欄では貼り付けた CR / CRLF が LF に変換されます。送信側が CRLF バイトで署名している場合は「CRLF 改行で署名する」をオンにすると、計算前に各 LF を CRLF に戻します。

わずかな文字の違いも影響します。JSON の再シリアライズ、末尾改行の削除、空白の変更、URL コンポーネントのデコード、パース済みボディの使用は別のダイジェストになります。ヘッダーの16進部分だけをコピーすると sha256= や v1= の接頭辞が欠けますが、このツールはどちらも受け付けます。

このページが確認しないこと

検証は HMAC のバイトを比較するだけです。古いタイムスタンプや再生イベントを拒否せず、プロバイダーの許容時間も判定せず、送信側へ通信しません。

汎用 Webhook では base64 を受け付けますが、GitHub と Stripe は 16 進数を送るため、この 2 つに base64 検証は用意していません。漏れたシークレットのローテーションや失効はサーバー側の作業です。

最近使ったツール: