基本情報技術者試験問題に挑戦しよう!「メッセージ認証」~Pythonでつくって学ぶ~【GitHub対応】

セキュリティ GitHubでつくって学ぶ

基本情報技術者試験とは

基本情報技術者試験は、情報処理推進機構(IPA)が実施し、「情報処理の促進に関する法律」に基づき経済産業省が認定する国家試験である。

ITエンジニアとしてキャリアをスタートする方のIT基礎力を問う試験で、「ITエンジニアの登竜門」とも呼ばれる。

「基本情報技術者試験」の試験範囲は、IPAのWebサイトに掲載されているシラバスに明記されている。試験は、「科目A」で、知識を問う小問題と、「科目B」で、技能を問う小問題に分けて行われる。科目Aと科目Bの両科目で合格点を取らなければ、基本情報技術者試験の合格とはならない。


それでは、基本情報技術者試験(科目A)のサンプル問題にチャレンジしてみよう。

問32

メッセージ認証符号の利用目的に該当するものはどれか。
ア メッセージが改ざんされていないことを確認する。
イ メッセージの暗号化方式を確認する。
ウ メッセージの概要を確認する。
エ メッセージの秘匿性を確保する。

出典:基本情報技術者試験 科目A サンプル問題(2022年12月)

正解:ア

メッセージ認証とは

共通鍵を用いて、メッセージの内容が改ざんされていないことを確認する仕組みである。
事前に送信者と受信者で共通鍵を共有しておく。

送信者側

  1. メッセージと共通鍵を基に、ハッシュ関数を用いて、メッセージ認証コード(MAC:Message Authentication Code)を生成する。
  2. メッセージとMACを受信者へ送信する。

受信者側

  1. 受信したメッセージと共通鍵を基に、同じハッシュ関数を用いてMACを生成する。
  2. 受信者は、送信されたMACが生成したものと一致するか検証する。

ここで、MAC値が一致すれば、受信者は改ざんされていないことを確認できる。秘密鍵を知らない第三者が正しいMACを生成することを困難にするため、第三者によるメッセージの偽造を検出するのにも役立つ。


(以下、2026.9.22追記・2026.9.23一部修正)

今回は、これを実際にPythonで計算して、値がどう変わるかを目で見るところまで試してみよう。

(注意)記事内で紹介しているPythonプログラムは、説明のための抜粋である。そのままコピペしても実行できないことがある。完全版のコードは、以下の筆者のリポジトリに置いている。

pc-labo-fe-exam-python / 04_message_ninshou

【つくって学ぶ】簡易MACをPythonで計算する

まずは仕組みを一番シンプルに再現する。
「鍵とメッセージをくっつけてSHA-256でハッシュ化する」自作MAC関数である。
これはMACの考え方を学ぶための簡易例であり、実際のシステムでは使用しないこと。

import hashlib

def simple_mac(key: str, message: str) -> str:
    """鍵とメッセージを連結してSHA-256でハッシュ化する簡易MAC"""
    data = (key + message).encode("utf-8")
    return hashlib.sha256(data).hexdigest()

key = "himitsu-no-kagi"
message = "10000円を送金します"

mac1 = simple_mac(key, message)
print("元のメッセージ :", message)
print("MAC            :", mac1)

(実行結果)

元のメッセージ : 10000円を送金します
MAC            : 56c825134dbfd7f047f444b16e7d3ca5913bf84f60540e08aa5d1a8e6a49ffcc

これが「メッセージ+鍵」から作られたMAC値である。
ここからが本題、「変えたらどう変わるか」を実験していこう。

【実験1】メッセージを改ざんしてみる

送金額を「10000円」から「90000円」に書き換えて、同じ鍵でMACを計算し直してみよう。

tampered = "90000円を送金します"
mac2 = simple_mac(key, tampered)
print("改ざん後メッセージ:", tampered)
print("MAC              :", mac2)
print("MACは一致する?   :", mac1 == mac2)
改ざん後メッセージ: 90000円を送金します
MAC              : 52bd7d350319a711278f8949f7fb668367bd9b1220e964662ee7d14bcb78add3
MACは一致する?   : False

数字を1文字変えただけなのに、MACは全くの別物になった。受信者は届いたMACと自分で計算したMACを比べるだけで、「あ、これは元のメッセージと違う」とすぐに気づける。
これが「改ざん検知」の正体である。

【実験2】鍵が違うとどうなるか(なりすまし対策)

今度はメッセージは元に戻して、共通鍵を知らない誰かが偽のMACを作ろうとした場合を試してみよう。

wrong_key = "chigau-kagi-desu"
mac3 = simple_mac(wrong_key, message)
print("別の鍵で計算したMAC:", mac3)
print("MACは一致する?    :", mac1 == mac3)
別の鍵で計算したMAC: 7d6eff38d36d79dea2d044a4f552150947dfa2ae29658981f6b8c0235e1744a5
MACは一致する?    : False

正しい鍵を知らないと、正しいMACは作れない。これが「なりすまし対策」にもなる理由である。攻撃者はメッセージを好きに書き換えられても、共通鍵を知らない限り、それに対応する正しいMACを計算できない。

【実験3】同じ鍵・同じメッセージなら、何度計算しても同じ結果

最後に、改ざんも鍵の変更もせず、そのまま計算し直してみよう。

mac4 = simple_mac(key, message)
print("再計算したMAC:", mac4)
print("MACは一致する?:", mac1 == mac4)
再計算したMAC: 56c825134dbfd7f047f444b16e7d3ca5913bf84f60540e08aa5d1a8e6a49ffcc
MACは一致する?: True

当たり前のようだが、これも大事な性質である。「同じ入力からは必ず同じMACが出る」からこそ、受信者は送信者と全く同じ計算をすることで検証ができる。

【注意】この自作MACには弱点がある

ここまで作った simple_mac は「鍵とメッセージを連結してハッシュ化するだけ」なので、仕組みの理解には十分ですが、実務ではこのまま使うべきではない。ハッシュ関数の内部構造によっては、鍵を知らなくても既存のMACから「メッセージの末尾に何かを付け足した場合の正しいMAC」を計算できてしまうケースがあるためである(長さ拡張攻撃と呼ばれる)。

そのため実際には、Pythonの標準ライブラリにある hmac モジュールで実装された HMAC を使うのが定石である。

import hmac as hmac_lib

def real_hmac(key: str, message: str) -> str:
    return hmac_lib.new(key.encode("utf-8"), message.encode("utf-8"), hashlib.sha256).hexdigest()

print("HMAC(元メッセージ) :", real_hmac(key, message))
print("HMAC(改ざん後)     :", real_hmac(key, tampered))
HMAC(元メッセージ) : a5ac69186540f85cbc22a0992a2e32f52c1f664ef38dcebb6265787e88c25094
HMAC(改ざん後)     : c018bc7cfef689be241208f7dc533c0c75730ac307a9ba30994ee52376fcb70c

やっていることの見た目は simple_mac とそっくりだが、HMACでは、秘密鍵から作った内側・外側のパッド(ipad、opad)を使って、ハッシュを二重に適用する構造になっている。length extension attackなどへの耐性がある。「値がガラッと変わって改ざんが検知できる」という体験としては同じだが、本番で使うならこちらのHMACと覚えておこう。

まとめ

やったこと分かったこと
メッセージを1文字変えるMACが全く別の値になる → 改ざん検知
鍵を変える正しいMACが作れなくなる → なりすまし対策
同じ入力で再計算必ず同じMACになる → 検証が成立する理由

「メッセージ認証符号は改ざん検知に使う」という一文を暗記するより、実際に1文字変えてMACの値が別物になる瞬間を見たほうが、記憶に残るはず。この問題も、これで自信を持ってアを選べるだろう。


この記事のコード(完全版)

この記事で紹介したコードの完全版・実行可能な状態のものは、以下の筆者のリポジトリに置いている。
pc-labo-fe-exam-python / 04_message_ninshou

コメント

タイトルとURLをコピーしました