HMAC完全ガイド:仕組み・安全性・実装とベストプラクティス
はじめに:HMACとは何か
HMAC(Hash-based Message Authentication Code)は、メッセージ認証コード(MAC)の一種で、共有秘密鍵とハッシュ関数を組み合わせてメッセージの完全性(integrity)と認証(authenticity)を提供します。HMACは広く使われており、TLS、IPsec、SSH、JWT、各種API署名や認証プロトコルの基盤技術として採用されています。標準的な定義はRFC 2104およびNISTのFIPS 198-1に示されています。
基本的な構造と数式表現
HMACは次のように定義されます(簡略化した表現):
- HMAC(K, m) = H((K' ⊕ opad) || H((K' ⊕ ipad) || m))
ここで、Hはハッシュ関数(例:SHA-256)、Kは秘密鍵、mはメッセージ、K'はブロック長Bに合わせた鍵(KがBバイトより長ければH(K)を用い、短ければゼロパディングする)、ipadはバイト値0x36をBバイト分繰り返したもの、opadはバイト値0x5cをBバイト分繰り返したもの、||は連結を表します。
処理の流れ(実装観点)
- 鍵の正規化:鍵KがハッシュのブロックサイズBを超える場合はH(K)を取り、Bより短ければ0でパディングしてK'を作る。
- 内向きハッシュ:K' ⊕ ipad とメッセージmを連結してハッシュを計算する(内側ハッシュ)。
- 外向きハッシュ:K' ⊕ opad と内側ハッシュの結果を連結してハッシュを計算する(外側ハッシュ)。
- 外側ハッシュの出力が最終HMAC値である。必要に応じて出力を切り詰め(truncation)して使うこともある。
なぜこの構造か(設計意図)
HMACは単純にH(K || m)の形ではなく二重ハッシュ(inner/outer)を採用することで、ハッシュ関数の内部構造に依存する攻撃(例:長さ拡張攻撃)や鍵の流出リスクを低減します。二段階で鍵が別のマスク(ipad/opad)と結合されるため、攻撃者が内側の状態から直接鍵を推定することを困難にします。理論的な安全性解析はBellare・Canetti・Krawczykらの研究により示されています。
安全性の要点
- セキュリティの上限は、主にハッシュ関数の出力長(例:SHA-256なら256ビット)と鍵長によって決まる。実効的にはmin(鍵のビット長, ハッシュ出力長)程度の安全性と見なせる。
- HMAC自体は長さ拡張攻撃に対して安全である。これは内側のハッシュ結果を外側で再ハッシュする構造による。
- ただし、ハッシュ関数の重大な弱点(例えば衝突が非常に容易になるような場合)はHMACの安全性にも影響を与える可能性がある。一般に衝突耐性や圧縮関数の性質が重要。
- 理論的証明により、HMACはハッシュ関数が擬似ランダム関数(PRF)として振る舞う限りにおいて安全であることが示されている(Bellare, Canetti, Krawczyk)。
ハッシュ関数とパラメータの選び方
推奨事項:
- 既知の脆弱性があるもの(例:SHA-1)は新規用途には避ける。現状の標準はSHA-256以上(SHA-256 / SHA-384 / SHA-512)。
- ハッシュのブロックサイズに注意:SHA-256のBは64バイト、SHA-512は128バイト。鍵の正規化処理はこれに従う。
- 鍵長は少なくともハッシュ出力長に達することが望ましい(例えばHMAC-SHA256なら256ビット)。実務上は十分にランダムな256ビット以上の鍵を推奨。
- パフォーマンスや帯域の制約がある場合は出力切り詰め(例:128ビット)を行うことがあるが、セキュリティとトレードオフになるため慎重に決める。
典型的な用途と実例
- TLS 1.2 以前では、データのMACにHMACを使用(ただしTLS 1.3ではAEADに移行)。
- IPsec(AH/ESP)での整合性検証。
- JWT(JSON Web Token)での署名(例:HS256はHMAC-SHA256)。
- APIキー/署名(AWS署名Version 4等)でのリクエスト認証。
- PBKDF2などの鍵導出関数(KDF)でHMACをPRFとして利用。
実装上の注意(落とし穴とベストプラクティス)
- 定数時間比較:MACの検証はタイミング攻撃を避けるため定数時間比較関数で行うこと。単純なmemcmpは短絡的な不具合を招く。
- 鍵管理:鍵は十分にランダムで長く、安全に保管する。鍵を再利用しすぎないこと(用途ごとに鍵を分けることが望ましい)。
- ライブラリの利用:言語/環境で提供される標準のHMAC実装(OpenSSL、libsodium、BoringSSL、標準ライブラリなど)を利用し、自前実装は避ける。
- 出力切り詰め:切り詰めを行う場合はその安全性評価を行い、受信側も同じルールで検証する。
- 鍵の長さ調整:鍵がハッシュのブロックサイズより長い場合、実装は自動でH(K)を計算して正規化することを確認する(多くのライブラリで自動化されている)。
既知の攻撃と対策
代表的な攻撃とその対策:
- 総当たり(ブルートフォース)攻撃:鍵が短い場合に有効。対策は長くランダムな鍵を使用すること。
- ハッシュの弱点を突く攻撃:基礎となるハッシュ関数に深刻な脆弱性(容易な衝突)が見つかった場合はHMACの安全性も低下する可能性がある。対策は強力なハッシュへの移行。
- タイミング攻撃・副チャネル攻撃:検証実装のタイミング差異から情報が漏れる可能性がある。対策は定数時間比較と安全な実装。
- リプレイ攻撃:HMACはメッセージ改竄を検出するが、同じ正当なメッセージを再送されるリプレイを防ぐ機能はない。対策はnonceやタイムスタンプ、シーケンス番号等を組み合わせること。
HMACと他のMAC方式の比較
- CMAC(ブロック暗号ベース): AESベースのMACであり、ハッシュ以外の選択肢。ハードウェアでのAESアクセラレーションがある場合に有利。
- Poly1305: 高速で小さな鍵を用いることができる一方、ワンタイムキーや一部の用途で要件があるため用途を選ぶ。
- GMAC: GCMモードに付随する認証タグを利用する方式で、暗号化+認証(AEAD)を実現するAES-GCMの一部として使われる。
- デジタル署名(RSA/ECDSA): 非対称鍵を使い否認防止や公開検証が必要な場合に用いる。HMACは共有鍵ベースであり否認防止は提供しない。
実務での推奨設定(チェックリスト)
- ハッシュ関数: 最低SHA-256以上を利用。
- 鍵長: 少なくともハッシュ出力長と同等(例:256ビット)を推奨。
- 鍵管理: 安全なKMSやHSMで保管し、アクセス制御を適切に行う。
- 検証処理: 定数時間での比較を実装または既存ライブラリを使用。
- ログ・エラーメッセージ: 認証失敗時に詳細エラーを出しすぎない。
- 移行計画: 既知の弱いハッシュを使っている場合は強力なハッシュへ計画的に移行する。
相互運用性とテスト
RFC 4231 等にはHMAC-SHA系のテストベクタが掲載されており、実装の相互運用性を確認するためにこれらのベクタを使った単体テストを行うことが重要です。多くのライブラリは標準的なHMAC APIを提供しており、それらを利用して検証済みの結果を得ることが推奨されます。
まとめ
HMACは、シンプルで理論的裏付けのある安全なメッセージ認証方式です。正しいハッシュ関数と適切な鍵管理、そして安全な実装(定数時間比較を含む)を組み合わせることで、高い実用性と安全性を確保できます。一方で、用途に応じてAEADや他のMAC(CMAC、Poly1305など)を検討することも大切です。特に暗号化と認証を同時に行いたい場合はAEADの採用を検討してください。
参考文献
- RFC 2104 - HMAC: Keyed-Hashing for Message Authentication
- FIPS PUB 198-1: The Keyed-Hash Message Authentication Code (HMAC)
- RFC 4231 - Test Cases for HMAC-MD5 and HMAC-SHA-1 and HMAC-SHA-224/256/384/512
- Bellare, Canetti, Krawczyk: Keying Hash Functions for Message Authentication (HMAC security analysis)
- RFC 6234 - US Secure Hash Algorithms (SHA-1, SHA-224, SHA-256, SHA-384, SHA-512)
投稿者プロフィール
最新の投稿
建築・土木2025.12.25空気ばねの原理・設計・施工と維持管理 — 建築・土木分野での詳細ガイド
IT2025.12.25A14 Bionicの徹底解説:設計、性能、機械学習、実世界での評価
建築・土木2025.12.25矩計図の書き方と読み方:設計者と施工者が押さえる実務ガイド
建築・土木2025.12.25局所排気装置(LEV)の設計・運用と維持管理 — 建築・土木現場の空気質対策ガイド

