はじめに
デジタル通信の世界では、メッセージがプライベートに保たれるだけでなく、転送中に改ざんされていないこと(完全性)と、主張された送信者から本当に送信されたものであること(認証性)を保証することが極めて重要です。単純なハッシュ関数は偶発的なデータ破損をチェックできますが、悪意のある改ざんを防ぐことはできません。なぜなら、誰でも改ざんされたメッセージのハッシュを再計算できてしまうからです。
ここで登場するのが HMAC(Hash-based Message Authentication Code:ハッシュベースのメッセージ認証コード)です。HMAC は、暗号学的ハッシュ関数(例:SHA-256)と秘密鍵を組み合わせた、特定の種類のメッセージ認証コード(MAC)です。秘密鍵を所有している当事者のみが、特定のメッセージに対する HMAC を生成および検証できます。このプロセスは、データの完全性と認証性の両方を提供します。
この実験(Lab)では、HMAC の実践的な経験を積みます。まず概念を理解し、次に強力なコマンドラインツールである openssl を使用して鍵を生成し、HMAC を計算します。最後に、アプリケーション開発で一般的なタスクである、Python スクリプトで HMAC を実装する方法を確認します。
HMAC の概要
このステップでは、HMAC の基本的な概念と、それが安全な通信にとって不可欠である理由について説明します。
SHA-256 のような標準的なハッシュ関数は、入力メッセージを受け取り、ハッシュまたはダイジェストとして知られる固定長の文字列を生成します。メッセージのビットが 1 つでも変更されると、結果のハッシュは完全に異なるものになります。これはデータの完全性をチェックするのに非常に優れています。しかし、認証性は提供しません。攻撃者がメッセージを傍受して変更した場合、改ざんされたメッセージの新しいハッシュを計算して送信するだけで済みます。受信者には、メッセージが変更されたことを知る方法がありません。
HMAC は、ハッシュ処理に秘密の共通鍵を導入することで、この問題を解決します。共通鍵とは、送信者と意図された受信者との間でのみ共有される秘密の情報の一部です。
HMAC のプロセスはおおよそ次のように機能します。
- 送信者は、秘密鍵とメッセージを結合します。
- この結合に対してハッシュ関数(例:SHA-256)が適用されます。
- 結果として得られたハッシュ(この時点では HMAC と呼ばれます)が、元のメッセージとともに送信されます。
受信者がメッセージと HMAC を受け取ると、秘密鍵のコピーを使用して同じ計算を実行します。
- 計算された HMAC が受信した HMAC と一致する場合、受信者はメッセージが変更されていないこと(完全性)と、秘密鍵を持っている誰かから送信されたこと(認証性)を知ることができます。
- HMAC が一致しない場合、メッセージは侵害されたと見なされ、破棄されるべきです。
このステップは純粋に概念的なものです。次のステップでは、この理論を実践に移します。
HMAC 秘密鍵の生成
このステップでは、HMAC のセキュリティの基盤となる、安全でランダムな秘密鍵を生成します。予測可能な鍵では、攻撃者が HMAC を偽造できてしまいます。ここでは、多用途な暗号化コマンドラインユーティリティである openssl ツールを使用します。
ランダムなデータを生成するために openssl rand コマンドを使用します。
-hex: このオプションは、opensslにランダムなデータを 16 進数文字列として出力するように指示します。32: これは生成するランダムバイトの数を指定します。32 バイトは 256 ビットに相当し、特に SHA-256 ハッシュアルゴリズムと組み合わせて使用される、強力で一般的に使用される鍵長です。
後続のコマンドで鍵を簡単に使用できるように、生成した鍵を HMAC_KEY という名前の環境変数に格納します。ターミナルで次のコマンドを実行してください。
export HMAC_KEY=$(openssl rand -hex 32)
このコマンドは openssl rand -hex 32 を実行し、その出力(16 進数の鍵)を取得して HMAC_KEY 変数に割り当てます。
echo コマンドを使用して、生成した鍵を表示できます。
echo $HMAC_KEY
長い 16 進数の文字列表が表示されるはずです。あなたの鍵は一意なものになります。
0db348c78473ce8460416f875cd87239d0f5f66fbe5103ba4b5c84cf2cd76914
秘密鍵が用意できたので、HMAC を作成する準備が整いました。
HMAC-SHA256 の計算
このステップでは、生成した鍵を使用してサンプルメッセージの HMAC を計算します。まず、メッセージを含むファイルを作成しましょう。
echo コマンドを使用して message.txt という名前のファイルを作成します。-n フラグは重要です。これは、echo が文字列の末尾に改行文字を追加するのを防ぎ、それによってコンテンツ、ひいては最終的な HMAC が変更されるのを防ぐためです。
echo -n "This is a secret message." > message.txt
これでメッセージと鍵が揃ったので、HMAC を計算できます。メッセージダイジェスト(ハッシュ)の計算に使用される openssl dgst コマンドを使用します。
-sha256: SHA-256 ハッシュアルゴリズムを使用することを指定します。-mac hmac: HMAC メソッドを使用してメッセージ認証コード (MAC) を計算することを指定します。-macopt hexkey:$HMAC_KEY: これは MAC アルゴリズムのオプションを提供します。ここでは、鍵が 16 進数形式 (hexkey) であることを指定し、以前に作成した環境変数$HMAC_KEYを使用して鍵自体を渡します。message.txt: 認証対象のデータを含む入力ファイルです。
HMAC を生成するには、次のコマンドを実行します。
openssl dgst -sha256 -mac hmac -macopt hexkey:$HMAC_KEY message.txt
出力は、秘密鍵で計算されたメッセージの HMAC ダイジェストになります。出力形式は、使用されたアルゴリズムと結果の HMAC 値を示します。
HMAC-SHA2-256(message.txt)= 214fbb56f716dfe1c2f4a60615a5b901b263fd74c9678b2aef4f01779b34dea8
この HMAC 値は、秘密鍵を共有する受信者にメッセージとともに送信するものです。
HMAC の整合性検証
このステップでは、HMAC 検証プロセスがどのように機能するかを確認します。正しい鍵を使用した場合に成功し、誤った鍵を使用した場合やメッセージが変更された場合に失敗する様子を観察します。
正しい鍵での検証
検証は特別なコマンドではなく、受信者が独自に HMAC を再計算し、受信したものと比較する行為そのものです。前のステップのコマンドを再度実行すると、全く同じ HMAC 値が得られます。これは、鍵とメッセージが変更されない限り、HMAC が一貫していることを確認します。
誤った鍵での失敗の観察
次に、異なる鍵でメッセージを検証しようとすることで、攻撃者や不適切な設定をシミュレートしてみましょう。まず、新しい「誤った」鍵を生成します。
export WRONG_KEY=$(openssl rand -hex 32)
次に、元の message.txt に対して、この WRONG_KEY を使用して HMAC を計算してみます。
openssl dgst -sha256 -mac hmac -macopt hexkey:$WRONG_KEY message.txt
出力には新しい HMAC 値が表示されます。
HMAC-SHA2-256(message.txt)= 781729497e89f3f9cb1d8c7ab632e22753062ac39cd64de0e5b81a45de245d78
この HMAC が、正しい $HMAC_KEY で生成したものとは全く異なることに注目してください。これは、正しい秘密鍵がなければメッセージに対する有効な HMAC を生成できず、それによって認証性が保証されることを示しています。
メッセージが変更された場合の失敗の観察
メッセージ自体が改ざんされた場合に何が起こるかも見てみましょう。message.txt を少し変更します。
echo -n "This is a tampered message." > message.txt
次に、元の正しい鍵 ($HMAC_KEY) を使用して、再度 HMAC を計算します。
openssl dgst -sha256 -mac hmac -macopt hexkey:$HMAC_KEY message.txt
ここでも、全く異なる HMAC 値が得られます。これは、メッセージに対するいかなる変更(たとえごくわずかであっても)も検出され、それによって完全性が保証されることを証明しています。
Python での HMAC 実装
このステップでは、Python を使用して HMAC 処理をプログラムで実行する方法を学習します。これは、メッセージのセキュリティを確保する必要がある Web アプリケーション、API、その他のソフトウェアで一般的に要求されるタスクです。Python の標準ライブラリには、この目的のために hmac モジュールと hashlib モジュールが提供されています。
メッセージの HMAC-SHA256 を計算するための簡単な Python スクリプトを作成します。まず、nano テキストエディタを使用してファイル hmac_example.py を開きます。
nano hmac_example.py
次に、次の Python コードを nano エディタにコピー&ペーストします。このコードは、必要なライブラリをインポートし、鍵とメッセージを定義した後、HMAC を計算して出力します。
注記: この例では、鍵とメッセージをハードコーディングしています。実際のアプリケーションでは、鍵は安全に保存・管理されます。鍵とメッセージの両方はバイト文字列である必要があるため、先頭に b を付けています。
import hmac
import hashlib
## シークレットキー (バイト列である必要があります)
## 実際のアプリケーションでは、安全な場所から取得します
key = b'\x0d\xb3\x48\xc7\x84\x73\xce\x84\x60\x41\x6f\x87\x5c\xd8\x72\x39\xd0\xf5\xf6\x6f\xbe\x51\x03\xba\x4b\x5c\x84\xcf\x2c\xd7\x69\x14'
## 認証するメッセージ (バイト列である必要があります)
message = b'This is a secret message.'
## 1. 新しい HMAC オブジェクトを作成
## - 鍵を渡す
## - メッセージを渡す
## - ハッシュアルゴリズムを指定する (hashlib から)
h = hmac.new(key, message, hashlib.sha256)
## 2. 16 進数形式でダイジェストを取得
hex_digest = h.hexdigest()
print("HMAC Digest:")
print(hex_digest)
コードを貼り付けた後、ファイルを保存し、Ctrl+O、ファイル名を確認するために Enter、最後に終了するために Ctrl+X を押して nano を終了します。
次に、ターミナルから Python スクリプトを実行します。
python3 hmac_example.py
スクリプトが実行され、計算された HMAC ダイジェストが出力されます。
HMAC Digest:
214fbb56f716dfe1c2f4a60615a5b901b263fd74c9678b2aef4f01779b34dea8
これで、Python で HMAC 生成を正常に実装できました。これは、安全なソフトウェアを構築する際に直接応用できるスキルです。
まとめ
この実験(Lab)では、現代の暗号技術の礎石であり、データの完全性と認証性を保証する Hash-based Message Authentication Code (HMAC) に関する実践的な経験を積みました。
以下の点を学びました。
- HMAC は、暗号学的ハッシュ関数と秘密鍵を組み合わせてメッセージ認証コードを作成する。
- 秘密鍵を持つ当事者のみが HMAC を生成または検証できるため、不正な改ざんや偽造を防ぐことができる。
- コマンドラインツール
opensslは、ランダムな鍵の生成 (openssl rand) や HMAC の計算 (openssl dgst) を含む暗号操作を実行するための強力なユーティリティである。 - メッセージのわずかな変更や誤った鍵の使用は、全く異なる HMAC を生じさせ、改ざんが容易に検出可能になる。
- Python は、アプリケーションに HMAC 機能を容易に統合するための
hmacライブラリとhashlibライブラリを提供している。
HMAC を習得することにより、より安全で信頼性の高いシステムを構築するための重要な一歩を踏み出しました。



