ハッシュ衝突攻撃の系譜(MD5・SHA-1 はなぜ破られたか)
なぜ MD5 や SHA-1 を今すぐ捨てるべきかが腑に落ちます。誕生日攻撃の数理から差分解読、chosen-prefix 衝突、Flame と SHAttered までを時系列で整理します。
- 1.衝突耐性は誕生日攻撃により出力長 n ビットの半分、約 2 の n/2 乗で頭打ちになる。MD5 の 64 ビット・SHA-1 の 80 ビットという理論限界が、差分解読でさらに大きく削られて実用的に破られた。
- 2.MD5 は 2004 年に衝突が、2009 年に chosen-prefix collision が確立。これを悪用したのが 2012 年の Flame マルウェアで、偽の Microsoft コード署名証明書を生成した。SHA-1 は 2017 年の SHAttered で実衝突が公開された。
- 3.破られたのは衝突耐性であり、原像耐性(ハッシュ値から元データを逆算)はまだ実用上残る。だが署名や証明書は衝突耐性に依存するため、MD5・SHA-1 は署名用途では完全に使用禁止。
ハッシュが「破られた」とは何が壊れたのか
暗号学的ハッシュ関数には3つの安全性要件があります。MD5 や SHA-1 が「破られた」と言うとき、実際に壊れたのはそのうちのどれなのかを最初に切り分けておくと、なぜ署名は危険でパスワード保存の文脈では事情が違うのか、までが正確に理解できます。要件の定義は 暗号の基礎 でも触れた通りですが、ここでは攻撃の難易度差まで踏み込みます。
| 安全性要件 | 攻撃者の目標 | 理想的な計算量(n ビット) | 現状(MD5/SHA-1) |
|---|---|---|---|
| 原像耐性 | ハッシュ値 h から H(m)=h となる m を1つ求める | 2 の n 乗 | 実用上は健在 |
| 第二原像耐性 | 与えられた m1 とは別の m2 で H(m1)=H(m2) を作る | 2 の n 乗 | 実用上は健在 |
| 衝突耐性 | H(m1)=H(m2) となる任意の対 (m1, m2) を見つける | 2 の n/2 乗(誕生日攻撃) | MD5・SHA-1 とも崩壊 |
ここで決定的なのは、衝突耐性だけが、攻撃者が両方のメッセージを自由に選べる点です。原像・第二原像は標的のハッシュ値やメッセージが先に固定されますが、衝突は攻撃者が2つとも作り込めるため、誕生日のパラドックスが効いて計算量が一気に下がります。
誕生日攻撃:なぜ n ビットが n/2 ビットになるのか
「23人いれば誕生日が一致する確率が50%を超える」という誕生日のパラドックスが、衝突探索の数理そのものです。出力が n ビットなら取り得る値は 2^n 通りですが、ランダムに約 2^(n/2) 個のメッセージをハッシュした時点で、その中のどこかに同じ値の対が現れる確率が約 50% に達します。
出力空間のサイズ N = 2^n
k 個ハッシュしたとき、全て相異なる確率 ≈ exp( -k(k-1) / (2N) )
衝突が出る確率が 1/2 になる k ≈ 1.1774 * sqrt(N) ≈ 2^(n/2)
直感的には、k 個の要素からは k(k-1)/2 通りの対が作れ、各対が衝突する確率が 1/N。期待衝突数が 1 を超えるのは k ≈ sqrt(N) のときです。つまり総当たりの平方根まで落ちる。
原像探索(特定の h を狙う)は N = 2^n 回の試行が要りますが、衝突探索は2つのメッセージ群の「ぶつかり」を探すので sqrt(N) = 2^(n/2) で済みます。MD5 は 128 ビット出力なので衝突耐性の理論限界は 2^64、SHA-1 は 160 ビットで 2^80。この「半分」が、署名アルゴリズムに最低 256 ビット級(SHA-256)が要求される根拠です。メモリを使わない衝突探索には Floyd のサイクル検出や、並列化に向く van Oorschot–Wiener の distinguished-point 法が使われます。
注意すべきは、2^64 や 2^80 はあくまで汎用の誕生日攻撃の上限だという点です。MD5 や SHA-1 が現実に破られたのは、ここからさらに内部構造を突く差分解読で計算量を削ったからです。
差分解読:構造を突いて誕生日限界を割り込む
MD5・SHA-1 はどちらも Merkle–Damgård 構造 で、固定長の圧縮関数を反復します。**差分解読(differential cryptanalysis)**は、入力に特定の差分(XOR 差)を与えたとき、それが圧縮関数の各ラウンドをどう伝播するかを追い、**最終的に差分が打ち消し合って出力差がゼロになる差分経路(differential path)**を構築する手法です。
1. メッセージ対 (M, M') の差分 ΔM = M XOR M' を設計
2. 各ラウンドで内部状態の差分 ΔH がどう変化するかを追跡
3. ローテーション・加算・非線形関数で差分が「都合よく相殺」する
経路を、確率を最大化しながら探索
4. その経路を満たす実際のメッセージ対を、条件を解いて構成
→ H(M) = H(M') を直接作れる(誕生日攻撃を経由しない)
王小雲(Wang Xiaoyun)らの 2004〜2005 年の成果が転換点でした。MD5 については 2^39 回程度(当時のPCで数時間〜数分)で衝突を生成し、SHA-1 についても 2^69(後に 2^63)と、誕生日限界の 2^80 を大きく下回る攻撃経路を示しました。理論限界より速いという事実こそが、これらの関数が「設計として壊れた」ことの証拠です。
2004 年に最初に作られた MD5 衝突は、共通プレフィックスの後ろにアルゴリズムが計算した制御ビット列を続けた、人間にとって無意味な2つのブロックでした。この段階(identical-prefix collision)では、攻撃者が衝突の「中身」を自由に選べないため、悪用は限定的に見えました。脅威が現実の証明書偽造へと跳ね上がるのは、次の chosen-prefix collision の登場を待つことになります。
chosen-prefix collision:任意の前半を選べる衝突
実害を決めたのは衝突の自由度です。2種類を区別します。
- identical-prefix collision(共通接頭辞衝突):両メッセージが同じ接頭辞
Pを共有し、攻撃者が作った衝突ブロックを続ける。形はP || C1とP || C2。前半は同一でなければならない。 - chosen-prefix collision(選択接頭辞衝突):攻撃者が任意に選んだ異なる2つの接頭辞
P1、P2から出発し、それぞれに別の衝突ブロックを付けて全体のハッシュを一致させる。形はP1 || C1とP2 || C2。
Merkle–Damgård の反復性が鍵です。P1 と P2 を処理し終えた時点の内部状態(chaining 値)は普通は異なりますが、その差分を打ち消す衝突ブロック対 (C1, C2) を差分解読で構成できれば、以降の処理は完全に一致し、最終ハッシュも一致します。P1・P2 を自由に選べるので、攻撃者は意味のある2つの文書(たとえば内容の異なる2枚の証明書)を衝突させられる。
state(P1) ──┐ ┌── 同じ chaining 値
├ 差分 Δ を C1,C2 で吸収 →─┤ → 以降の追記が共通なら
state(P2) ──┘ └── 最終ハッシュも一致
MD5 の chosen-prefix collision は 2007〜2009 年に Stevens・Lenstra・de Weger らが確立しました。これが、現実のインフラを揺るがす攻撃の弾になります。
系統と時系列:MD5 から SHA-1 崩壊まで
衝突攻撃の発展を年代・分岐で整理します。重要なのは「衝突生成の理論」と「現実の悪用」が交互に駆動した点です。
| 年 | 出来事 | 対象 | 種別・意義 |
|---|---|---|---|
| 1996 | Dobbertin が MD5 圧縮関数の衝突を示唆 | MD5 | 構造的弱点の早期警告 |
| 2004 | Wang らが MD5 の実衝突を公開(数時間で生成) | MD5 | identical-prefix collision |
| 2005 | Wang らが SHA-1 を 2^69 で攻撃可能と発表 | SHA-1 | 誕生日限界 2^80 を下回る理論攻撃 |
| 2008 | 偽の CA 証明書を MD5 衝突で作成(Sotirov ら) | MD5 | chosen-prefix の実証 PoC |
| 2012 | Flame マルウェアが MD5 衝突で署名証明書を偽造 | MD5 | 国家級の実攻撃に悪用 |
| 2017 | SHAttered が SHA-1 の実衝突 PDF を公開 | SHA-1 | 初の実用的 identical-prefix collision |
| 2019-2020 | SHA-1 の chosen-prefix collision を現実化(Leurent–Peyrin) | SHA-1 | PGP 鍵偽造まで到達、完全終焉 |
Flame(2012):MD5 衝突が国家級攻撃に化けた瞬間
Flame は中東を標的にした高度なスパイ用マルウェアです。最も衝撃的だったのは、Windows Update の仕組みを悪用するために、Microsoft の正規 CA から発行された証明書を出発点に、MD5 の chosen-prefix collision で偽のコード署名証明書を捏造した点でした。当時 Microsoft の一部のライセンスサービスがまだ MD5 ベースの証明書を発行しており、攻撃者は正規証明書と同じ MD5 ハッシュを持つ偽証明書を作成。これにより、Microsoft が署名したかのように見える悪性コードを Windows に受け入れさせ、LAN 内で正規アップデートを装って感染を広げました。署名の信頼が PKI の連鎖に依存している以上、その根のハッシュが衝突可能なら連鎖全体が崩れる、という教訓です。
SHAttered(2017):SHA-1 初の実衝突
Google と CWI が公開した SHAttered は、同じ SHA-1 ハッシュを持つ2つの異なる PDF ファイルを実際に生成して見せました。計算量は約 2^63.1 で、内訳は約 900 京回の SHA-1 計算。GPU 換算で膨大なコストですが「不可能」ではないことを証明しました。これは identical-prefix collision で、2つの PDF は共通接頭辞の後に衝突ブロックを仕込み、PDF の描画オブジェクト切り替えの仕掛けで「同じハッシュ・異なる表示内容」を実現していました。
SHAttered は identical-prefix でしたが、2020 年に Leurent と Peyrin が SHA-1 の chosen-prefix collision を約 2^63.4・クラウドで数万ドル規模まで現実化しました。これで SHA-1 は MD5 と同じ「任意文書の衝突」段階に達し、PGP/GnuPG の Web of Trust における鍵証明書の偽造まで実証されました。SHA-1 はもはや署名・証明書のいかなる用途でも安全余裕がゼロです。
衝突できても原像はできない:射程の限界
ここまでの攻撃はすべて衝突耐性に対するもので、原像耐性は別問題です。攻撃者は「同じハッシュを持つ2つを自分で作る」ことはできても、「世の中にある特定のハッシュ値から元データを逆算する」ことは依然 2^n に近い困難さを保ちます。MD5・SHA-1 に対する実用的な原像攻撃は今も存在しません。
この非対称性が用途別のリスクを分けます。
| 用途 | 依存する性質 | MD5/SHA-1 の危険度 | 理由 |
|---|---|---|---|
| デジタル署名・証明書 | 衝突耐性 | 致命的・即時禁止 | 攻撃者が2文書を衝突させ、署名を別文書に流用できる |
| ファイル完全性検証(改ざん検知) | 第二原像耐性 | 高い(非推奨) | 攻撃者が原本を用意できれば衝突文書を仕込める |
| パスワード保存 | 原像耐性(+低速性) | 衝突は無関係だが別の理由で不可 | そもそも高速ハッシュは総当たりに弱い |
| HMAC(鍵付き認証) | 擬似ランダム性 | 現時点で実用上は破られていない | 鍵が混ざり衝突経路を攻撃者が制御できない |
パスワード保存で MD5/SHA-1 を避けるべき理由は衝突攻撃ではなく、高速すぎて総当たり・レインボーテーブルに弱いことと、原像探索の文脈だからです。ここは パスワードの安全な保存 と ハッシュ化と暗号化の違い で扱う「ソルト+低速ハッシュ(bcrypt/Argon2)」の話になります。衝突攻撃の議論とは軸が違う点を混同しないこと。
移行と防御の実務
対策は単純で、署名・証明書・改ざん検知の用途では MD5・SHA-1 を SHA-256 以上(または SHA-3)へ移行すること。誕生日攻撃の 2^(n/2) を踏まえれば、衝突耐性を 128 ビット以上確保するには最低 256 ビット出力が要ります。主要 CA は 2017 年までに SHA-1 証明書の発行を停止し、ブラウザも SHA-1 証明書を拒否済みです。
完全な置き換えがすぐにできない場合の中間策として、SHAttered の著者らは衝突ブロックの特徴を検知する sha1collisiondetection(counter-cryptanalysis)を公開しており、Git なども導入しています。ただしこれは延命策にすぎません。新規設計では SHA-256 を既定とし、将来の暗号アジリティを見据えるなら 暗号アルゴリズムの系統樹 で整理した世代交代の観点で選定するのが筋です。
- 破られたのは衝突耐性のみ。原像・第二原像は実用上健在。署名が危険なのは署名が衝突耐性に依存するから。
- 衝突耐性の理論限界は誕生日攻撃で
2^(n/2)。MD5=2^64、SHA-1=2^80。差分解読でさらに下回って実破された。 - identical-prefix(前半共通)と chosen-prefix(前半を任意選択)の差が実害を決める。証明書偽造には chosen-prefix が要る。
- Flame(2012)= MD5 chosen-prefix で署名証明書偽造。SHAttered(2017)= SHA-1 初の実衝突 PDF。
- 署名・証明書・改ざん検知では SHA-256 以上へ移行。パスワードは別軸(低速ハッシュ+ソルト)。
ハッシュ衝突攻撃の系譜は、「理論上の弱点」が放置されれば必ず「現実の攻撃」に育つことの教科書例です。誕生日攻撃で半減した安全余裕を、差分解読がさらに削り、chosen-prefix が実害の扉を開けた――この連鎖を辿れると、なぜ暗号の世界が「破られる前に移行する」予防原則で動くのかが腑に落ちます。
セキュリティ Article
ハッシュ衝突攻撃の系譜(MD5・SHA-1 はなぜ破られたか)を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
ハッシュ
比較で見る軸
難易度: advanced / カテゴリ: セキュリティ / タグ数: 6
導入後に効く点
MD5 は 2004 年に衝突が、2009 年に chosen-prefix collision が確立。これを悪用したのが 2012 年の Flame マルウェアで、偽の Microsoft コード署名証明書を生成した。SHA-1 は 2017 年の SHAttered で実衝突が公開された。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- セキュリティ
- タグ数
- 6
判断チェックリスト
- 自社の用途が「ハッシュ / MD5」に近いか確認する。
- 強みである「衝突耐性は誕生日攻撃により出力長 n ビットの半分、約 2 の n/2 乗で頭打ちになる。MD5 の 64 ビット・SHA-1 の 80 ビットという理論限界が、差分解読でさらに大きく削られて実用的に破られた。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。