SECURITY / DATA INTEGRITY
メッセージ認証符号(MAC)とは?注文データの書き換えを見抜く「秘密の合言葉」
カフェに送った注文が「1,500円」から「15,000円」に書き換えられたら、店側はどうやって気付くのでしょう。通信の途中で変わった内容を検知する仕組みの一つが、メッセージ認証符号(MAC)です。
1. まずは、ネット注文の「金額すり替え」を考える
スマートフォンから注文を送るとき、サーバに届くのは画面そのものではなく「商品・数量・金額」などを記したデータです。もし途中でそのデータが改変されたら、画面に表示された金額と請求金額が食い違うかもしれません。
送信前
コーヒー 1杯
1,500円
途中で改変
「0」を1個追加
15,000円
受信時の確認
元の内容と一致?
秘密の鍵を使ってチェック
MACは「メッセージそのもの」に、送る側と受け取る側だけが知る共通鍵を組み合わせて作る、小さな検査用データです。元のメッセージとMACをセットで送ります。
2. MACの仕組みは「同じ合言葉で答え合わせ」
たとえば家族だけが知っている合言葉を使い、メモの内容に応じたチェック番号を作る、と考えてみてください。合言葉を知らない人がメモを書き換えても、正しい番号まで作り直すことは困難です。暗号学的MACは、この考え方を数学的に強くしたものです。
送る人(注文アプリ)
メッセージ + 共通鍵
注文データ + MACを送信
受け取る人(店舗サーバ)
届いたメッセージ + 同じ共通鍵
届いたMACと比較する
正規の2者が同じ鍵を使い、内容も変わっていなければMACは一致します。途中で金額を変えた場合、攻撃者が鍵を知らなければ正しいMACを作り直せないため、受信側で不一致を検出できます。
ここで確認できることは2つ
① 完全性:途中で内容が変更されていないか。
② メッセージの認証:共通鍵を知る主体が生成したと考えられるか。
ただし「その2者のうち、どちらが作ったか」を外部の人に証明する機能ではありません。
3. いちばん重要な落とし穴:転送先の第三者には証明できない
注文アプリのアリスと店舗のボブが、同じ秘密の鍵を知っているとします。アリスが注文を送った後、ボブがその注文データとMACを第三者のチャーリーに転送しました。
アリス
共通鍵あり
ボブ
共通鍵あり
チャーリー
共通鍵なし
アリス → ボブ:注文+MAC
ボブ → チャーリー:転送
チャーリーは共通鍵を持っていないため、自分でMACを再計算して検証できません。さらに、ボブもアリスと同じ鍵を持っているので、ボブ自身が別の注文と正しいMACの組を作ることも可能です。したがって「これは確かにアリスだけが作った注文だ」と第三者へ証明できません。
この点が、後で説明する電子署名との大きな違いです。MACは、鍵を共有する当事者同士の確認に向いています。
4. 実際に改ざんしてMACを比べてみよう
次のラボでは、最初は金額が正しい注文を送ります。まず「途中で金額を10倍に書き換える」を押してみてください。鍵やメッセージの条件を変えると、検査結果も変化します。
HANDS-ON LAB
注文データを途中で書き換えてみる
「メッセージ」と「秘密の鍵」が同じときだけ、受信側の計算結果が一致する様子を試せます。表示される4桁の値は学習用の簡略モデルで、実際の暗号学的MACではありません。
① 送信者が作った注文
商品: マグカップ / 数量: 1 / 金額: 1,500円
最初につけたチェック値:C6C1
② 受信者に届いた注文
商品: マグカップ / 数量: 1 / 金額: 1,500円
届いたチェック値:C6C1
③ 受信者が自分の鍵で再計算
再計算したチェック値:C6C1
✓ 一致:この鍵で検証した範囲では内容が整合
注意:このシミュレーターは計算の一致・不一致を理解するためのものです。実運用では標準のHMAC-SHA-256などを利用し、タグの比較にはタイミング攻撃に配慮したAPIを使います。またMAC単体ではリプレイ攻撃を防げません。
「受信者がタグを作り直す」を押すと、同じ鍵を持つ受信者も整合するメッセージとタグを作れる、というMACの重要な性質を観察できます。実際の送受信では、元のタグを勝手に差し替えることが認められるわけではありません。
5. ハッシュ値だけでは、なぜ不十分なのか
ハッシュ関数は、データから「指紋」のような値を計算します。1文字変えると通常は大きく異なる値になります。しかしハッシュ関数自体は誰でも実行できます。
| 方式 | 必要な秘密 | 何が分かる? |
|---|---|---|
| 通常のハッシュ | なし | 比較元が信頼できる場合の変化の確認 |
| MAC / HMAC | 共通鍵 | 鍵を知る相手との完全性・メッセージ認証 |
| 電子署名 | 署名者の秘密鍵 | 公開鍵による第三者検証が可能 |
たとえば攻撃者が注文金額を書き換え、公開されているハッシュ関数で新しいハッシュ値も計算し直して送れば、単純な「注文+ハッシュ値」の仕組みでは見抜けません。一方MACでは秘密の共通鍵が計算に必要です。
6. HMACとCMACは、MACの代表的な作り方
HMAC:ハッシュ関数を使う
HMACはSHA-256などの暗号学的ハッシュ関数と秘密鍵を組み合わせる方式です。単純に「鍵とメッセージをつなげてハッシュする」だけではなく、規格で定められた内側・外側の処理を用います。Web APIやWebhookの署名検証でよく見かける方式です。
表記イメージ
tag = HMAC-SHA256(secret_key, request_body)受信側も受信したボディの正確なバイト列で再計算します。JSONの空白やキーの順序を勝手に変更すると、計算値が変わる場合があります。
CMAC:ブロック暗号を使う
CMACはAESなどのブロック暗号を基にしたMACです。HMACと同じく鍵を共有する当事者がメッセージの完全性を検証します。用途や利用可能な暗号ライブラリ、プロトコル仕様に応じて選択します。
どちらも「MACである」という性質は共通です。MACは必ずしもメッセージを暗号化するわけではありません。機密性(他人に読めないこと)が必要なら、TLSや認証付き暗号(AEAD)など、別の適切な仕組みも必要です。
7. MACと電子署名を「荷物の受領書」で比べる
MACは、2人だけが使える共通のスタンプに似ています。受け取った側は本物のスタンプか確かめられますが、自分でも同じスタンプを押せるため、第三者にはどちらが押したのか分かりません。
一方、電子署名は、署名者だけが持つ秘密鍵で署名を作り、誰でも参照できる公開鍵で検証します。公開鍵と本人の結び付けが適切に保証されていれば、第三者にも署名の正当性を示せます。ただし秘密鍵の管理が悪ければ、その保証は崩れます。
MAC
作成:共有する秘密鍵
検証:同じ秘密鍵
共有相手との通信に向く
電子署名
作成:署名者の秘密鍵
検証:対応する公開鍵
第三者にも検証してもらえる
8. 現場で使うときに気を付けたいこと
鍵をコードやURLに埋め込まない
秘密鍵ではなく『共通鍵』ですが、漏えいすれば第三者でも正しいMACを作れます。シークレット管理基盤で保管し、必要に応じて更新します。
比較は安全なライブラリで
通常の文字列比較は、実装によっては比較時間からヒントを与えます。信頼できるMAC検証APIや定数時間比較を利用します。
リプレイ攻撃は別に防ぐ
有効な注文データとMACをそのまま再送する攻撃は、MACだけでは防げません。タイムスタンプ、nonce、重複防止IDなども検証します。
データの表現を一致させる
送信と受信で改行・文字コード・JSONのシリアライズ結果が異なると不一致になります。どのバイト列を認証するか、あらかじめ厳密に決めます。
まとめ:「改ざんしていない」と「誰が作った」は別の問い
MACは、メッセージと共通鍵から作る検査用の値です。受信者は同じ鍵で再計算し、届いた値と比較することで、メッセージの完全性と共有鍵を知る主体による生成を確認できます。
しかし共有鍵を持つ人なら誰でもMACを作れるため、第三者に「この人だけが送った」と示すことはできません。当事者同士ならMAC、第三者にも検証してほしいなら電子署名――この使い分けが理解できれば、仕組みの核心をつかめています。