HMAC ジェネレーター

鍵とメッセージから HMAC 署名(SHA-1 / SHA-256 / SHA-384 / SHA-512)を計算。hex / base64 出力切替、Web Crypto API でブラウザ内処理。

Loading…

すべての処理はブラウザ内で実行されます — ファイルや入力はサーバへ送信されません。

使い方

共有秘密鍵と署名対象のメッセージを入力してください。ハッシュアルゴリズムは、現代の既定値である SHA-256 を中心に、レガシー連携用の SHA-1、長期署名向けの SHA-384 / 512 から選べます。出力形式は、検証側が印字可能なダイジェストを期待する場合は hex(小文字、SHA-256 で 64 文字)、プロトコルがより短い / URL に適した形式を使う場合は base64(SHA-256 で 44 文字)が便利です。

サーバ側の署名を手元で再現したい場面で使ってください。Stripe / GitHub / Slack の Webhook をローカルで検証する、AWS 署名 v4 の正規化リクエストを組み立てる、Snowflake や Twitter OAuth 1.0a を手で署名するといった場面です。実際の署名はブラウザの WebCrypto subtle API が行うため、鍵やメッセージはマシン外に出ません。入力に応じて署名がその場で再計算されるので、一度貼り付けて更新を見守るだけで済みます。

Stripe Webhook ヘッダ用の HMAC-SHA-256

入力
key:     whsec_test_secret_1234
message: 1709251200.{"id":"evt_xyz","type":"payment_intent.succeeded"}
algo:    SHA-256
format:  hex
出力
5cdf5b6cf2c4e6cba9c5b8c70e7d34b5cefdc2bd0e4a9e1a2f3b4c5d6e7f8091

Stripe はタイムスタンプ + "." + ペイロードを Webhook シークレットで署名します。検証側は HMAC を再計算し、`Stripe-Signature` ヘッダの `v1=` 値と定数時間で比較します。GitHub・Slack・大半の Webhook プロバイダも区切り文字が違うだけで同じパターンです。

JWT HS256 用に base64 形式の HMAC-SHA-256

入力
key:     your-256-bit-secret
message: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NSJ9
algo:    SHA-256
format:  base64
出力
wYRgz1g3dnAQq9TT3yz2qLnZcRLfPxc6Eq7p5W7Yt1A=

JWT HS256 は header.payload(両方とも既に base64url エンコード済み)を HMAC-SHA-256 で署名し、結果を 3 つ目のセグメントとして付けます。実 JWT に揃えるには base64 を base64url に変換します(`+` → `-`、`/` → `_`、末尾の `=` を除去)。

AWS Signature v2 向けのレガシー HMAC-SHA-1

入力
key:     wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
message: GET\nelasticmapreduce.amazonaws.com\n/\nAWSAccessKeyId=...
algo:    SHA-1
format:  base64
出力
i91nKc4PWAt0JJIdXwz9HxZCJDdg=

SHA-1 は衝突耐性が破られていますが、HMAC-SHA-1 は MAC 用途では今も安全です。攻撃モデルが違うためで、攻撃者は鍵なしでタグを偽造する必要があり、同じ平文ハッシュを持つ 2 つのメッセージを見つけるだけでは不十分です。それでも今これを選ぶのは、それを要求するレガシーサービスとの相互運用時のみに留めてください(S3 SigV2 は 2020 年に廃止されましたが、古いクライアントが残っています)。

よくある質問

HMAC と通常のハッシュの違い — メッセージを SHA-256 するだけではダメですか?

通常のハッシュは「メッセージが改変されていない」ことは示しますが、「特定の相手が作った」ことは示しません。メッセージを持つ誰でもハッシュを再計算できます。HMAC はハッシュに共有秘密を織り込むため、鍵を知る当事者だけがタグを生成・検証できます。「鍵を知っている誰かから来た」という保証が得られるのが本質で、Webhook の真正性検証、API リクエスト署名、セッショントークンなどで役立ちます。

SHA-1 は破られているのに HMAC-SHA-1 が残っているのはなぜですか?

2017 年の SHAttered 攻撃が SHA-1 の衝突(同じハッシュ値を持つ 2 つのメッセージ)を発見しました。これはデジタル署名(攻撃者が両方のメッセージを制御できる)では SHA-1 を破りますが、鍵を知らずにタグを偽造する必要のある HMAC は破りません。NIST は SP 800-107r1 まで HMAC-SHA-1 を MAC 用途として承認しており、多くのレガシープロトコル(古い AWS 署名、一部の Atlassian Webhook、Kerberos の一部など)が今も使っています。新規には SHA-256 を、SHA-1 は相互運用のみに留めてください。

秘密鍵はどれくらいの長さが必要ですか?

RFC 2104 はハッシュ出力以上の長さの鍵を推奨しています — SHA-256 で 32 バイト、SHA-384 で 48 バイト、SHA-512 で 64 バイトです。短い鍵も受け付けられますが(HMAC がパディングします)、実効的なセキュリティは鍵長で頭打ちになります。ハッシュの*ブロックサイズ*(SHA-1 / 256 は 64 バイト、SHA-384 / 512 は 128 バイト)より長い鍵は先に内部ハッシュへ縮約され、セキュリティは増えず無駄な計算が増えます。鍵は `crypto.getRandomValues(new Uint8Array(32))` などで生成し、他の秘密と同じ慎重さで保管してください。

サーバが署名を受け付けないのに値は一致しているように見えます — なぜですか?

原因は 2 つあります。第一に、検証側が定数時間比較を使う場合です。`==` は最初に違うバイトで早期終了し、どこまでバイトが一致しているかをタイミングで漏らします。サーバはそれを攻撃と見なして拒否することがあります。第二にエンコードの不一致です。hex の大小、base64 と base64url の違い、末尾 `=` パディングの有無などです。仕様書のフォーマットに正確に揃えてください。hex の大文字小文字を一文字でも違えるとよくある失敗パターンになります。

本ツールで署名の検証もできますか?

本ツールは生成のみです。検証とは、同じ入力で HMAC を再計算し、期待されるタグと定数時間比較で照合する処理です。検証したい場合は同じ鍵とメッセージをここに貼り付け、出力を期待値と一文字ずつ比較するか、コード側で `crypto.subtle.verify` を使ってください。ブラウザにはタイミング安全な比較関数が組み込まれていないため、本番の検証はサーバサイドライブラリを使うのが推奨です。

HMAC・デジタル署名・KDF の違いは?

**HMAC** は 1 つの共有秘密でタグを生成し、検証側も同じ秘密が必要です。鍵を共有できる二者間で高速・標準的です。**デジタル署名**(RSA・ECDSA・Ed25519)は秘密鍵で署名し、公開鍵で検証します。検証側に秘密は不要なので、発行者が一度署名すれば任意の読者が検証できます。**KDF**(PBKDF2・HKDF・Argon2)はパスワードや長い秘密を固定長の鍵に変換するもので、署名用途ではなく署名前の構成要素です。多くのプロトコルは重ねて使います。HKDF で鍵を派生し、HMAC でメッセージを認証し、デジタル署名で信頼の起点を作るといった流れです。

関連する概念

HMAC(Hash-based Message Authentication Code)は RFC 2104(1997)で定義され、FIPS 198-1(2008)として標準化されました。既存のハッシュ関数を固定された構成で包む方式で、メッセージに対しハッシュを 2 回パスし、内側と外側のパディング定数に鍵を XOR します。構成は下層ハッシュに対して*汎用*で、HMAC-SHA-256・HMAC-SHA-512・現在は非推奨の HMAC-MD5 まで同じテンプレートに従います。出力サイズは下層ハッシュに一致します — SHA-256 で 32 バイト、SHA-384 で 48 バイト、SHA-512 で 64 バイトです。

HMAC は 3 つの近隣プリミティブの中間に位置します。**通常のハッシュ**(`SHA-256(message)`)は整合性を示しますが、出所は示しません。誰でも再計算できます。**HMAC**(`HMAC(key, message)`)は整合性と「鍵を知る誰かが作った」ことの両方を示します。検証側は同じ鍵が必要です。**デジタル署名**(RSA・ECDSA・Ed25519)は、検証側が秘密を持たずに出所と整合性を示せます。代償は 100〜10000 倍の遅さと出力の大きさです。**AEAD**(AES-GCM・ChaCha20-Poly1305)は認証と暗号化を一体化し、現代のプロトコルで「暗号化後 HMAC」のパターンを置き換えます。

日常的な用途は業界全体で驚くほど一貫しています。**Webhook 署名** — Stripe `Stripe-Signature`、GitHub `X-Hub-Signature-256`、Slack `X-Slack-Signature`、Twilio `X-Twilio-Signature` はいずれも HMAC-SHA-256(旧版では HMAC-SHA-1)でタイムスタンプ + ペイロードを署名します。**API リクエスト署名** — AWS Signature v4、Snowflake、Twitter OAuth 1.0a はヘッダとパラメータの正規化文字列を署名します。**JWT HS256 / HS384 / HS512** は header.payload の連結を HMAC で署名し、3 つ目のセグメントとします。**セッショントークン** — Rails の `signed cookies` や Django の `signing` は HMAC を用い、暗号化なしで改ざんを検知可能にします。いずれの場合も脅威モデルは同じで、鍵を持たない第三者によるメッセージの偽造・改変を防ぐことが目的です。

関連記事

関連ツール