MiServe DevTools

あなたのステッカー

ツールをここにピン留めできます。このブラウザに保存されます。

HMAC 生成ツール

シークレットキーを使い、HMAC-SHA256 などのハッシュでメッセージに署名します。受け取った署名の検証もできます。

HMAC(hex)
HMAC(Base64)

WebAssembly を使ってブラウザ内で動作します。貼り付けた内容はアップロードされません。

このツールについて

HMAC で証明できること

HMAC(RFC 2104)は、ハッシュ関数を通してメッセージとシークレットキーを組み合わせ、短いタグを返します。同じ鍵を持っていれば、誰でも同じタグを計算し直せます。2 つのタグが一致すれば、メッセージは途中で改ざんされておらず(完全性)、鍵を知っている人が作成したものだとわかります(真正性)。

単なるハッシュではこれができません。メッセージを書き換えた人は、そのハッシュも計算し直せるからです。HMAC はメッセージを隠さないので、暗号化ではありません。また、双方が同じ鍵を持つため、2 人のうちどちらがメッセージを書いたかは示せません。それには、秘密鍵を使うデジタル署名が必要です。

Webhook の署名

HMAC をよく目にする場面の一つが Webhook です。送信側のサービスは、受信側と共有しているシークレットでリクエストボディに署名してタグをヘッダーに入れて送り、受信側のサーバーはリクエストを信頼する前に同じ HMAC を計算します。GitHub は X-Hub-Signature-256: sha256=… を hex で、Shopify は X-Shopify-Hmac-SHA256 を Base64 で送ります。Stripe はタイムスタンプ、ドット、ボディをつないだものに署名し、その結果を Stripe-Signature の中の v1=… として送ります。

署名の対象は、届いたままのボディの生のバイト列です。フレームワークが JSON をパースし、それを再度シリアライズすると、空白やキーの順序が変わって HMAC が一致しなくなります。ここで署名が一致しないときは、まず鍵のエンコード(テキスト、hex、Base64)を、次にメッセージ末尾の改行を確認してください。

サーバーで定数時間比較を行う理由

通常の文字列比較は、最初に異なる文字が見つかった時点で終わります。そのためサーバーでは、偽造された署名の先頭バイトが間違っていれば応答がわずかに速く、合っていればわずかに遅くなり、この差を測定できる攻撃者は有効なタグを 1 バイトずつ割り出せます。定数時間比較は、結果にかかわらずすべてのバイトを読みます。プラットフォームが提供する関数を使ってください。Node.js では crypto.timingSafeEqual、Go では hmac.Equal、Python では hmac.compare_digest、PHP では hash_equals です。

このページの照合欄も同じ方式で、両方の値をバイト列にデコードしてすべてを読みます。ただし、両方の値をすでに持っているブラウザのタブには隠すべきタイミング情報がないため、ここでの照合は、自分のコードが正しいタグを生成したかどうかを確かめるためのものです。

動作のしくみ

タグの計算には、Go の crypto/hmac パッケージを WebAssembly にコンパイルしたものを使い、ブラウザのバックグラウンドスレッドで実行します。メッセージは UTF-8 として扱い、何も追加・削除しません。ただし 1 点だけ変わる部分があります。ブラウザのテキストボックスは改行をすべて LF 1 文字として保持するため、CRLF の改行で届いたメッセージは、ここでは LF で署名されます。鍵は UTF-8 テキストとして扱い、指定した場合は hex または Base64 からデコードします。メッセージも鍵もどこにも送信されません。それでも、本番環境のシークレットは Web ページに入力しないほうが安全です。できるだけテスト用の鍵を使ってください。

よくある質問

HMAC がサーバーで計算した値と違うのはなぜですか?

よくある原因は、鍵を誤ったエンコードで読んでいる(hex や Base64 の鍵をプレーンテキストとして扱っている)こと、メッセージ末尾の改行や改行コードの違い、パースして再シリアライズしたボディ、ハッシュアルゴリズムの違いです。相手側の出力が hex と Base64 のどちらなのかも確認してください。

HMAC は、鍵の後ろにメッセージをつなげてハッシュ化するのと同じですか?

いいえ。SHA-256、SHA-512、SHA-1、MD5 では、鍵とメッセージをつなげたもののハッシュに対して伸長攻撃が可能です。ハッシュ値を見た人が、鍵を知らなくてもデータを追加して有効なハッシュ値を計算できてしまいます。HMAC は導出した 2 つの鍵で 2 回ハッシュ化するため、この穴をふさいでいます。

HMAC の鍵はどのくらいの長さにすべきですか?

ハッシュの出力長以上のランダムな鍵を使ってください。SHA-256 なら 32 バイト、SHA-512 なら 64 バイトです。それより長くしてもほとんど効果はなく、ハッシュのブロック長を超える鍵は先にハッシュ化されて短くなります。短い鍵や推測しやすい鍵は、既知のメッセージとタグの組 1 つに対して候補を試すことで見つけられてしまいます。

HMAC-SHA1 や HMAC-MD5 は破られていますか?

SHA-1 と MD5 を単体のハッシュとして破った衝突攻撃は、それらの HMAC の現実的な偽造にはつながりません。古いプロトコルでは今も使われていますが、新しく採用するなら HMAC-SHA256 以上を選んでください。

ハッシュのほかのツール