HMAC とは?鍵付きハッシュ認証を解説
HMAC は秘密鍵とメッセージを組み合わせた鍵付きハッシュで、その整合性と、鍵を持つ誰かから来たことの両方を証明します。
単純なハッシュはデータが変更されていないことを証明しますが、誰でも再計算できるため、誰が生成したかは証明しません。HMAC は共有された秘密鍵を混ぜることでこれを解決します。鍵を持つ者だけが有効な HMAC を生成できるため、送信者も認証します。これはまさに webhook の署名、CI パイプラインが検証するものを含めて、動作する仕組みです。
HMAC とは何か
HMAC は Hash-based Message Authentication Code の略です。秘密鍵をメッセージとハッシュ関数(SHA-256 など)と組み合わせて tag を生成します。秘密を共有する受信者は tag を再計算して比較します。一致すれば、メッセージが無傷であり鍵を持つ者によって作成されたことが証明されます。
なぜ単純なハッシュでは不十分か
素のハッシュには秘密がないため、誰でも任意のデータについて計算できます。これは偶発的な破損を検出しますが真正性を証明できません。メッセージを変える攻撃者は単にハッシュを再計算できるからです。HMAC の秘密鍵こそが tag を信頼できる送信者に結びつけるものです。
webhook のための HMAC
webhook プロバイダは共有された秘密を使って各ペイロードを HMAC で署名し、その結果の署名を header に入れます。受信者は同じ秘密で生の body に対して HMAC を再計算して比較します。異なれば、リクエストは偽造または改ざんされたものとして拒否されます。
CI における HMAC
webhook を受け取るパイプライン、つまり deploy をトリガーしたりイベントを処理したりするものは、偽造されたリクエストがパイプラインを起動できないよう、動作する前に HMAC 署名を検証すべきです。比較は、タイミングを通じて秘密が漏れないよう定数時間でなければならず、これはセキュリティスキャナがチェックする細部です。
# Verify an HMAC webhook signature before acting
steps:
- run: |
expected=$(printf "%s" "$BODY" | openssl dgst -sha256 -hmac "$SECRET" -hex)
test "sha256=$expected" = "$SIGNATURE_HEADER"Latchkey に関する注記
Latchkey パイプラインが webhook によってトリガーされるとき、保存された秘密で HMAC 署名を検証することが標準のガードです。秘密はログ内でマスクされ、検証は通常の job ステップとして実行されます。
重要なポイント
- HMAC は秘密鍵をハッシュに混ぜ込み、整合性と真正性の両方を証明します。
- 単純なハッシュは整合性のみを証明します。HMAC の秘密鍵は送信者も証明します。
- webhook は HMAC でペイロードに署名し、CI はリクエストに基づいて動作する前に署名を検証すべきです。