TL

長さ拡張攻撃(Length Extension Attack)と HMAC が安全な理由

secret‖message の素朴な MAC が鍵なしで偽造される仕組みを、Merkle–Damgård の内部状態から解明。なぜ HMAC や SHA-3 なら防げるかまで原理で腑に落ちます。

応用MACHMACハッシュSHA-256暗号認証最終更新: 2026-06-21
TL;DR要点だけ先に
  • 1.Merkle–Damgård 構造のハッシュは「最後の内部状態=出力値」なので、ハッシュ値を chaining 値として復元すれば、鍵を知らなくても続きから計算を再開できる。
  • 2.MAC = SHA-256(secret‖message) は長さ拡張攻撃で偽造可能。攻撃者は message とその長さだけ分かれば、secret 不明のまま padding 込みの追記メッセージに正しい MAC を付けられる。
  • 3.HMAC は H(key⊕opad ‖ H(key⊕ipad ‖ message)) と二重ネストし、外側ハッシュで内部状態を覆い隠す。SHA-3/BLAKE2 は構造上そもそも内部状態が出力に晒されない。

「ハッシュ値=内部状態」という落とし穴

SHA-256 のような Merkle–Damgård(MD)構造のハッシュは、固定長の圧縮関数 f を反復し、最後の chaining 値(内部状態)をそのまま出力します。この「内部状態の全部が出力に露出する」性質を突くのが**長さ拡張攻撃(length extension attack)**です。攻撃者は H(secret‖message) の値と message の長ささえ分かれば、secret を一切知らずに H(secret‖message‖padding‖追記) の正しいハッシュを計算できてしまいます。

これがなぜ実害になるか。鍵付きメッセージ認証コード(MAC)を MAC = SHA-256(secret_key‖message) と素朴に作る実装が、現実に偽造されるからです。MD 構造の前提(圧縮関数の反復・末尾の長さ埋め込み)は ハッシュ関数の内部構造 を、MAC が改ざん検知に使われる文脈は 暗号の基礎 を前提とします。

攻撃の手順を分解する

MD ハッシュの処理を思い出すと、攻撃が成立する理由が見えます。

H0 = IV(規格固定の初期値)
for i in 1..n:  Hi = f(Hi-1, Mi)   ← 前段の出力を次段の入力に
出力 = Hn(最後の chaining 値そのもの)

H(secret‖message) を計算した側は、内部で secret‖message をパディングしてブロックに分け、Hn まで回しています。攻撃者が得た MAC 値は、まさにこの Hn=最終内部状態です。攻撃の流れはこうです。

既知: M = message, T = SHA-256(secret‖M), len(secret) は推測 or 既知
1. glue padding を構築:
   secret‖M を埋めた際に付く「1ビットの1 + 0詰め + 元の長さ」を再現する。
   secret の長さが分かれば、このパディング P は完全に決定できる。
2. 攻撃者の追記 X を用意する。
3. SHA-256 実装の内部状態 H0..H7 を T で上書き初期化する(T = 内部状態だから可能)。
4. ブロック長カウンタを len(secret‖M‖P) に合わせ、X だけを追加で食わせる。
5. 得られた出力 T' は、なんと
      T' = SHA-256(secret‖M‖P‖X)
   の正しいハッシュになっている。

ポイントは手順3です。MD では Hn が出力なので、出力 T を内部状態に書き戻すだけで「secret‖M‖P まで処理し終えた直後の状態」を鍵なしで完全再現できます。あとは続きを食わせるだけ。攻撃者は secret の中身を一度も知る必要がありません。

偽造される具体例

secret を共有鍵に、message = "user=guest&amount=100"T = MAC がサーバーから返るとします。攻撃者は len(secret) を 0 から総当たり(鍵長は数十通り程度)しつつ、X = "&admin=true" を末尾に追記。glue padding が途中に挟まる醜い形になりますが、多くのパーサは後勝ちで admin=true を採用します。結果、secret 不明のまま改ざんメッセージに正規の MAC が付いてしまいます。

影響を受けるハッシュ、受けないハッシュ

長さ拡張は MD 構造に固有で、出力が内部状態の全体を晒すものだけが脆弱です。

ハッシュ構造長さ拡張攻撃
SHA-1 / SHA-256 / SHA-512Merkle–Damgård成立する(生の secret‖msg は危険)
SHA-224 / SHA-384MD だが出力を切り詰め不成立(内部状態の一部しか出ない)
SHA-512/256MD・別IV で半分だけ出力不成立(完全な内部状態を得られない)
SHA-3 / SHAKEスポンジ構造原理的に不成立(容量部 c が隠れる)
BLAKE2 / BLAKE3HAIFA系・末尾フラグ付き不成立(最終ブロックを別扱い)

SHA-224 や SHA-512/256 が安全なのは、内部状態より短い出力しか返さないからです。攻撃者は Hn の全ビットを得られないため、続きの計算に必要な初期状態を復元できません。BLAKE2 は最終ブロックに「これが最後」というフラグ(finalization flag)を立てて圧縮するため、攻撃者が同じ最終化を再現できず、続きを正当に伸ばせません。SHA-3 が無傷な理由は、出力に晒されない容量部 c が常に内部に残る構造にあり、詳しくは ハッシュ関数の内部構造 で扱っています。

HMAC はなぜ安全か:ネストが内部状態を覆う

HMAC(RFC 2104)は MD ハッシュの長さ拡張を、ハッシュを二重にネストすることで封じます。定義はこうです。

HMAC(K, m) = H( (K' ⊕ opad) ‖ H( (K' ⊕ ipad) ‖ m ) )

K'   : 鍵 K をブロック長に整える(長ければ H(K)、短ければ 0 埋め)
ipad : 0x36 をブロック長ぶん繰り返した内側パディング
opad : 0x5c をブロック長ぶん繰り返した外側パディング

安全性の核心は外側ハッシュです。攻撃者が手にする HMAC 値は、外側 H((K'⊕opad)‖inner) の出力。これを内部状態として書き戻しても、その先で得られるのは「(K'⊕opad)‖inner に追記したもの」のハッシュであって、HMAC の正しい再計算ではありません。内側ハッシュの出力(真に伸ばしたい状態)は外側ハッシュへの入力として既に飲み込まれ、外から触れない位置に隠れています。長さ拡張で伸ばせるのは最外殻だけで、そこには鍵 K'⊕opad が前置されているため、鍵なしには正しい状態を作れません。

2回のハッシュは固定オーバーヘッド

HMAC の外側ハッシュは「鍵パディング(1ブロック)+内側出力」という短い固定長の入力にしか効きません。メッセージ全長を2回走査するわけではなく、外側は数回の圧縮関数呼び出しで済みます。だから長いメッセージでも追加コストはほぼ一定で、これが H(secret‖msg) を素朴に避けつつ実用速度を保つ HMAC の巧さです。

本質は「内部状態を出力から切り離す」こと

長さ拡張の根本原因は「最終内部状態=公開出力」でした。HMAC・SHA-512/256・SHA-3・BLAKE2 はアプローチこそ違え、すべて攻撃者に渡る値と続行に必要な内部状態を一致させないという同じ防御に帰着します。HMAC は外側ハッシュで覆い、切り詰め系は状態の一部だけ見せ、スポンジは容量部を常に隠す。設計は別でも狙いは一点です。

実務での選び方

鍵付き認証が必要なら、結論はシンプルです。

  • 生の H(secret‖message) を MAC に使わない。 SHA-256/SHA-1/SHA-512 を直結する自作 MAC は長さ拡張で壊れます。
  • HMAC-SHA-256 を既定にする。 標準化され実装も豊富。検証時はタイミング攻撃を避けるため定数時間比較で照合します(== の早期 return は1バイトずつ漏らす)。
  • 新規設計なら KMAC や BLAKE2 の鍵付きモードも候補。 SHA-3 ベースの KMAC や、鍵を引数に取れる BLAKE2 は長さ拡張耐性が構造由来で、HMAC のネストすら不要です。
  • 暗号化と認証を同時に欲しいなら AEAD へ。 MAC を別建てするより、認証付き暗号で完全性と機密性を一体提供するのが現代の定石です(AEAD の設計原理)。

なお「ハッシュは改ざん検知に万能」という誤解は危険で、鍵のない素のハッシュは誰でも再計算できるため認証にはなりません。ハッシュと暗号化・認証の役割分担は ハッシュ化と暗号化の違い を参照してください。

押さえどころ
  • 長さ拡張攻撃の原因=MD 構造で「最終 chaining 値がそのまま出力」だから。出力を内部状態に書き戻して続行できる。
  • 攻撃者は message・その長さ・H(secret‖message) だけで、鍵なしに secret‖message‖glue padding‖追記 の正しいハッシュを作れる。
  • HMAC は二重ネストの外側ハッシュで内部状態を覆い隠して防ぐ。SHA-512/256 は切り詰め、SHA-3 は容量部、BLAKE2 は最終化フラグで防ぐ。
  • 鍵付き認証に生ハッシュ連結を使わず、HMAC(または KMAC/AEAD)を使うのが鉄則。検証は定数時間比較で。

ハッシュを「一方向の魔法」で済ませず、最後に何を出力しているかまで分解できると、secret‖msg がなぜ危険で HMAC のネストがなぜ効くのかが構造で理解できます。MD と非MD の違いを押さえれば、ハッシュ選定そのものが防御の一手になります。

セキュリティ Article

長さ拡張攻撃(Length Extension Attack)と HMAC が安全な理由を実務で読む

TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。

解決すること

MAC

比較で見る軸

難易度: advanced / カテゴリ: セキュリティ / タグ数: 6

導入後に効く点

MAC = SHA-256(secret‖message) は長さ拡張攻撃で偽造可能。攻撃者は message とその長さだけ分かれば、secret 不明のまま padding 込みの追記メッセージに正しい MAC を付けられる。

先に潰すリスク

用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。

数字・仕様の読み方
難易度
advanced
カテゴリ
セキュリティ
タグ数
6

判断チェックリスト

  • 自社の用途が「MAC / HMAC」に近いか確認する。
  • 強みである「Merkle–Damgård 構造のハッシュは「最後の内部状態=出力値」なので、ハッシュ値を chaining 値として復元すれば、鍵を知らなくても続きから計算を再開できる。」が本当に評価軸になるか確認する。
  • 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
  • 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
  • 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
  • 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。

次に確認する観点

MACHMACハッシュSHA-256暗号MACHMACハッシュ
参考: 公式情報