HMACは、メッセージが途中で改ざんされていないことを確認するための安全な方法です。
ハッシュだけより信頼でき、APIの署名やWebhookの検証などで広く使われます。
この記事では、基本から仕組み、使いどころ、注意点までを初心者向けにやさしく解説します。
HMACとは?メッセージ認証コードの基本
HMACの意味と役割
HMACの定義
HMACは、秘密鍵とメッセージから短い確認用コード(MAC)を作る仕組みです。
名前の通りHash-based(ハッシュを用いた) Message Authentication Codeの略で、ハッシュ関数と秘密鍵を組み合わせて計算します。
できあがる値は固定長で、メッセージの中身が少しでも変われば別の値になります。
なぜ「認証」なのか
同じHMACを作れるのは秘密鍵を知っている人だけだからです。
受信側は同じ鍵で計算して一致を確かめることで、改ざん検出(完全性)と送信者が鍵の保持者であることの確認(真正性)を同時に行えます。
ハッシュだけでは不十分な理由
ハッシュの性質
ハッシュ関数は、入力からダイジェスト(指紋)を作りますが鍵を使いません。
そのため、誰でも同じハッシュを計算できます。
メッセージが同じならハッシュも必ず同じで、データの同一性確認に便利です。
改ざん可能性の例
攻撃者がメッセージを変えて新しいハッシュを作ることができてしまいます。
つまりハッシュだけでは「正しい人が作ったか」を保証できません。
さらに一部のハッシュ関数には構造上の弱点があり、やり方次第で「見かけ上もっともらしい」ハッシュを作れることもあります。
HMACはこうした弱点を避ける設計になっています。
HMACでできること
改ざん検出
受け取ったメッセージが送信時から変わっていないかを検出できます。
1ビットでも違えばHMACが一致しません。
送信者の確認
送信者が秘密鍵の保有者かを確かめる目安になります。
鍵を知る相手同士の通信に向いています。
使えないこと(非否認性など)
第三者に対し「誰が作ったか」を証明する用途には向きません。
HMACは共通鍵方式なので、鍵を知る誰が作っても区別できないためです。
この用途ではデジタル署名(公開鍵暗号)を使います。
用語の確認
基本用語の意味
次の用語だけ押さえておくと理解が進みます。
メッセージ、秘密鍵、MAC、アルゴリズムの4つです。
| 用語 | 説明 | 初学者向けの例 |
|---|---|---|
| メッセージ | HMACを付けたいデータ本体 | リクエストボディ、URL、JSON文字列 |
| 秘密鍵(key) | メッセージと組み合わせてHMACを計算する秘密 | ランダム32バイトの値 |
| MAC(タグ) | 計算結果の短い値。検証に使う | 32バイト(HMAC-SHA-256) |
| アルゴリズム | どのハッシュ関数でHMACするか | HMAC-SHA-256, HMAC-SHA-512 |
ダイジェストとエンコード
計算結果は内部的にはバイナリ(生の32バイトなど)です。
表示や送受信では16進表現やBase64に変換します。
表現方法が一致しないと比較に失敗するので、片方が16進、小文字、もう片方がBase64のようなズレに注意します。
HMACの仕組みをやさしく解説
使う材料
秘密鍵
ランダムに生成した十分な長さの秘密鍵を使います。
人間が覚えられる短い文字列は避けます。
メッセージ
そのままの生データではなく、送受信で同じ並びになるよう「並べ方」を揃えるのがポイントです。
例えばJSONならキーの順番やスペースの扱い、URLならクエリの順序を統一します。
ハッシュ関数
HMACは下支えとしてハッシュ関数を使います。
選ぶ関数で出力長や速度が変わります。
ハッシュ関数の例
迷ったらHMAC-SHA-256が現在の標準的な選択です。
| ハッシュ関数 | 出力長 | 現在の評価(初心者向け要約) |
|---|---|---|
| SHA-256 | 32バイト | 推奨。汎用、実装豊富 |
| SHA-512 | 64バイト | 長いタグが必要な場合に。高速な環境も多い |
| SHA-1 | 20バイト | 非推奨(新規設計では使わない) |
送信側の手順
ステップ説明
送信側は鍵とメッセージからHMACを作って一緒に送るだけです。
流れは次の通りです。
- メッセージを用意し、文字コードはUTF-8、改行や空白を含め表現を統一します。
- HMAC-SHA-256のようにアルゴリズムを選びます。
- 秘密鍵とメッセージでHMACを計算します。
- 結果を16進やBase64など決めた形式にエンコードします。
- メッセージ本体とHMACをセットで送ります(ヘッダーや別フィールドで可)。
シンプルなたとえ
HMACは「鍵付きスタンプを押す」イメージです。
スタンプの見た目(HMAC)は公開できますが、スタンプそのもの(鍵)を知らない人は同じ印影を作れません。
受信側の手順
ステップ説明
受信側は同じ手順でHMACを再計算し、送られてきた値と比較します。
一致すれば改ざんなし、そうでなければ破棄します。
比較には固定時間比較(タイミング差が漏れにくい比較)を使えるライブラリを選ぶと安全です。
一致しない時の考え方
文字コードやエンコードの不一致が原因のことが多いです。
改行、空白、キー順序、16進の大文字/小文字などをまず確認しましょう。
ハッシュとの違い
秘密鍵の有無
ハッシュは誰でも作れるが、HMACは鍵を持つ人しか作れません。
これが真正性をもたらします。
衝突への強さ
ハッシュ関数自体の弱点があっても、HMACは設計上その影響を受けにくいよう工夫されています。
とはいえ古い関数(SHA-1など)は避けるのが無難です。
速度とコスト
HMACは高速で実装が簡単です。
公開鍵ベースの署名より計算負荷が低く、APIなど高頻度の検証に向いています。
HMACの使いどころと実装のイメージ
HMAC-SHA-256のよくある使い方
主なユースケース
最も一般的なのはAPIリクエスト署名とWebhook検証です。
ほかにもクッキーの改ざん防止、CSRFトークンの検証、アプリ内の設定ファイルの保護などで使われます。
「受け取ったデータが正しい送信者による改ざんなしのものか」を確かめたい場面に適しています。
APIリクエスト署名の流れ
サマリ
クライアントがリクエスト内容からHMACを作り、サーバが同じ方法で再計算して照合します。
時刻やノンスを含めて「古いリクエストの使い回し」を防ぎます。
具体例
- 署名対象文字列を決める(HTTPメソッド、パス、クエリ、ボディの要約、タイムスタンプなどを連結)。
- 秘密鍵と署名対象文字列でHMAC-SHA-256を計算。
- 結果をBase64にしてヘッダー(例: AuthorizationやX-Signature)に入れて送信。
- サーバは同じ手順で再計算して一致を確認。タイムスタンプが許容範囲かもチェックします。
クライアントに配った秘密鍵は漏洩リスクがあります。
最小権限のキーやローテーションを併用しましょう。
Webhook検証の流れ
サーバ側(送信元)
Webhookの本文(ボディ)とタイムスタンプからHMACを計算し、ヘッダーに付けて通知します。
ボディそのものを対象にするのが確実です。
受信側(あなたのサービス)
受信したボディをそのまま使ってHMACを再計算し、ヘッダーの値と固定時間比較で照合します。
さらにタイムスタンプの期限切れを拒否します。
パース後のJSON文字列ではなく、生の受信バイト列を使うのがコツです。
入力と出力
入力の定義
HMAC関数の入力は3つ(鍵、メッセージ、アルゴリズム)です。
文字コードはUTF-8に統一し、改行や空白、キー順序を決めてから計算します。
出力形式の違い
出力はバイナリのタグで、表現のためにエンコードします。
16進は読みやすく、Base64は短くなります。
Base64urlを使う場合は記号の違いに注意します。
| 例 | 入力(鍵, メッセージ) | アルゴリズム | 生の出力長 | 表現例 |
|---|---|---|---|---|
| A | “secret”, “hello” | HMAC-SHA-256 | 32バイト | 16進では64文字、小文字/大文字を統一 |
| B | ランダム32バイト, JSON本文 | HMAC-SHA-256 | 32バイト | Base64やBase64urlで短く表現 |
HMACの注意点とベストプラクティス
秘密鍵の長さと生成
推奨長
少なくとも16〜32バイト(128〜256ビット)のランダム鍵を使うと安心です。
短い鍵や推測しやすい文字列は避けます。
生成方法
OSの安全な乱数生成器を使って作ります。
人間が考えたパスワードをそのまま鍵にしないでください。
鍵の管理
保存
リポジトリに平文で置かないことが基本です。
クラウドのシークレットマネージャや環境変数、KMSなどを使います。
ローテーション
鍵にバージョン(例: kid)を付けて段階的に切り替えると安全です。
古い鍵も一定期間だけ検証に残し、完全移行後に無効化します。
比較の方法
固定時間比較関数を使える標準ライブラリを選びます。
通常の文字列比較は早く不一致を返すためタイミング差を悪用される可能性があります。
アルゴリズム選択
推奨
新規実装はHMAC-SHA-256が無難です。
広くサポートされ、速度と安全性のバランスが良いです。
避ける
HMAC-SHA-1やHMAC-MD5は新規設計では避けるのが一般的です。
互換性のために検証のみで受ける場合は、移行計画を立てましょう。
エンコードの統一
文字コードと改行
UTF-8に統一し、LFかCRLFかを固定します。
見えない差が一致失敗の原因になります。
正規化のポイント
JSONはキー順・スペース、URLはパラメータ順とエスケープ規則を決めてからHMACを計算します。
表記ブレの回避
16進は小文字/大文字を統一し、Base64とBase64urlを混同しないでください。
余分な0x接頭辞や改行、末尾の=の有無にも注意します。
署名との違い
対称鍵と公開鍵
HMACは共有の秘密鍵、デジタル署名は秘密鍵/公開鍵のペアを使います。
署名は公開鍵だけで検証でき、秘密を配らなくて済みます。
誰が検証できるか
HMACは鍵を知る人しか検証できません。
多くの第三者に配布して検証させる用途なら署名が向きます。
使い分け
高速で簡単に改ざん検出したいAPIや内部通信はHMAC、送信者を第三者に証明したい文書や公開配布物は署名を選ぶと覚えると良いです。
まとめ
HMACは「秘密鍵付きのハッシュ」で、改ざん検出と送信者確認を手軽に実現できる基本技術です。
ハッシュだけでは不十分な場面で力を発揮し、API署名やWebhook検証など現場で広く使われます。
実装では鍵の生成と管理、アルゴリズム選択、エンコードの統一、固定時間比較といったポイントを丁寧に押さえることが成功のコツです。
まずはHMAC-SHA-256を選び、入力の表現を揃え、出力の形式を固定するところから始めてみてください。
