同じJSONなのに、
署名が合わない。
raw bodyで比べる。
結論:送信元が本文へHMAC署名を付ける場合、n8nで解析し直したJSONではなく、受信した本文そのものからHMACを計算する。公開テンプレでは、正しい要求だけ200、改変・期限切れ・署名不備は同じ401で止める。
このページが合う人:n8nのWebhookでHMAC-SHA256署名を確認したい人、JSONは同じに見えるのに署名不一致になる人。
分かること:raw bodyを使う理由、Crypto認証情報の置き場所、拒否すべき入力、確認済みテンプレの使い方。
先に用意するもの:送信元の公式仕様にある署名対象、署名ヘッダー名、出力形式、timestamp規則。試験には本番値ではなく、試験用secretと合成JSONを使う。
次の行動:下の4項目を送信元仕様と照合する。本文だけをHMAC-SHA256で署名する形式なら、公開テンプレを非公開のまま取り込んで試す。
似た実装を先に見る:このHMACガードを含む公開テンプレが、awesome-n8n-templatesのPR #189として2026年8月15日にmainへマージされた。顧客案件の実績や本番保証ではなく、合成データで確認した公開テンプレ。
最初に、送信元仕様の4項目を見る
「HMAC-SHA256を使う」だけでは設定を決められない。送信元の公式ドキュメントで、次の4項目がすべて一致するか確認する。
| 確認するもの | 公開テンプレの前提 | 違う場合 |
|---|---|---|
| 署名対象 | 受信した本文全体 | timestamp・method・path・一部headerを含むなら計算式を変更 |
| header | X-Automation-Signature | 送信元指定の名前へ変更 |
| 形式 | sha256= + 64桁hex | Base64や別接頭辞なら形式と比較処理を変更 |
| 時刻 | 署名済み本文のsent_at | header内のtimestampを署名する形式なら取り出し方を変更 |
4項目のどれかが不明なら、推測して本番へ出さない。送信元が提供する署名生成例と試験用payloadを先に使う。
同じJSONでも、送った文字列が違えば署名は変わる
次の2つはJSONとして読むと同じ内容。しかし、空白と改行を含む実際のバイト列は異なる。上を署名して下を送れば、正しく拒否される。
{"event_id":"evt_example-0001","sent_at":1786723200,"payload":{"action":"example"}}
{
"event_id": "evt_example-0001",
"sent_at": 1786723200,
"payload": { "action": "example" }
}WebhookノードでRaw Bodyを有効にすると、受信本文をbinary propertyのdataとして後続へ渡せる。Cryptoノードはこのbinary dataへHMACを計算する。解析後の$json.bodyを文字列化し直さない。
業務処理より前に、4段階で止める
- 01 / RECEIVE
raw bodyを受信
WebhookでRaw Bodyを有効化。本文とheaderを受け取る。
- 02 / COMPUTE
HMACを計算
Crypto認証情報のsecretで、binary dataへSHA256を適用。
- 03 / CHECK
署名と時刻を確認
形式、digest、signed timestamp、event_id、Content-Typeを確認。
- 04 / RESPOND
200か401へ分岐
条件を満たす場合だけ受理。詳細を返さず同じ401で拒否。
公開ワークフローのCryptoノードにはsecretを含めていない。取り込み後、利用者自身のn8nでCrypto認証情報を作り、Compute Body HMACへ割り当てる。
n8n 2.33.7で確認した6ケース
外部サービスへ接続しない環境で、実在データを含まない要求だけを送った。確認したのは次のHTTP結果。顧客案件の実績や本番環境の安全性を示すものではない。
| 送った条件 | 結果 | 確認した意味 |
|---|---|---|
| 空白を含む本文 + その本文の正しい署名 | 200 受理 | raw bodyから計算できる |
| 空白を含む本文 + compact JSON側の署名 | 401 拒否 | JSONの再文字列化を使っていない |
| 本文を1項目改変 | 401 拒否 | 改変を受理しない |
| 正しく署名した期限切れ本文 | 401 拒否 | 5分より古い要求を受理しない |
| 署名headerなし | 401 拒否 | 未署名を受理しない |
| 署名形式が不正 | 401 拒否 | 想定外の形式を受理しない |
公開テンプレを試す手順
- ワークフローJSONを取り込み、公開しない状態を保つ。
- n8nのCrypto認証情報を作り、試験用HMAC secretを入れる。
- Compute Body HMACへ認証情報を割り当てる。
- 送信元仕様とheader名、署名対象、hex形式、timestamp規則を比べる。
- 合成JSONで、正しい署名と改変した本文を1回ずつ送る。
- 拒否側が後続処理へつながっていないことを確認してから、業務ノードを追加する。
まだn8n環境がない場合は、n8n Cloudとセルフホストの責任範囲を先に確認する。署名を試すためだけにVPSを契約せず、更新・バックアップ・復旧を誰が担当するかで選ぶ。
このテンプレをそのまま使えない条件
- 送信元が本文以外にtimestamp、method、path、headerを連結して署名する。
- digestがBase64、複数署名、鍵ID付き、公開鍵署名など別形式。
- 送信元専用のn8n Triggerノードが、すでに署名確認を内蔵している。
- 同じeventを5分以内に再送された場合も、必ず1回だけ処理する必要がある。
5分の時刻窓は古い要求を止めるが、窓の内側の重複は止めない。厳密な二重処理防止には、署名済みのevent IDを永続保存し、処理前に使用済みか確認する。
本番前に追加で確認するものは、鍵の切替、時計ずれ、送信元の再試行、同一eventの重複、本文サイズ、レート制限。今回の確認には本番負荷試験と各社Webhookとの接続を含めていない。
よくある質問
JSONの内容が同じでもHMAC署名が一致しないことはある?
ある。空白、改行、キー順などが変わると送信バイト列が変わる。送信元が署名した本文そのものを使って計算する。
5分以内のtimestampなら同じWebhookを何度送っても安全?
安全とは限らない。時刻の確認は古い要求を拒否するもの。同じ時間内の重複には、event IDなどを保存して二重処理を止める仕組みが別に必要。
StripeやGitHubへそのまま使える?
そのまま使えるとは限らない。送信元ごとに署名対象と形式が違う。専用Triggerノードが署名確認を内蔵している場合もあるため、送信元とn8nの現行公式仕様を先に確認する。
公式情報
広告・確認範囲
本ページに第三者アフィリエイト広告なし。自社の有料構築サービス案内を含む。AUTOMATION NOTEはn8n公式・認定パートナーではない。
確認日:2026-08-15 / n8n 2.33.7 / 合成データ6ケース / 外部サービス接続なし / 本番負荷・各社互換性は未確認