プロトコルダウングレードとバージョン交渉攻撃の系譜
後方互換のために残した弱い選択肢が、まるごと攻撃の入口になる。FREAK・Logjam・DROWN・POODLE がなぜ成立したかを交渉の原理から押さえれば、TLS 1.3 のダウングレード防止が効く理由まで一気に腑に落ちます。
- 1.ダウングレード攻撃は MITM が交渉を細工し、両端を弱い暗号や旧バージョンへ引きずり下ろす手口。FREAK(512ビット RSA)・Logjam(512ビット DH)・DROWN(SSLv2 を別ポートで悪用)・POODLE(SSLv3 へ落とす)が代表例。
- 2.根本原因は交渉メッセージが鍵確立前に平文で飛び、後から認証されないこと。DROWN は同じ鍵を別プロトコルで使い回す cross-protocol 攻撃で、弱い方式を一つ残すだけで強い接続まで巻き添えになる。
- 3.防御は弱い選択肢を規格から排除し、交渉全体を強い鍵と署名に拘束すること。TLS 1.3 は (EC)DHE 専用化+ CertificateVerify で transcript に署名し、さらに ServerHello.random と TLS_FALLBACK_SCSV にダウングレード番兵を埋め込む。
ダウングレード攻撃とは:交渉を「最弱」へ引きずる
ダウングレード攻撃(downgrade attack)とは、中間者(MITM)がプロトコルのバージョン交渉や暗号スイート交渉を改ざんし、両端を本来選ぶはずだった強い方式から、より弱い方式へ意図的に引きずり下ろす攻撃です。攻撃者はアルゴリズムそのものを数学的に解くのではなく、「弱い選択肢が候補に残っている」という運用上の隙と、「交渉のやり取りがその場で認証されない」という構造上の隙を突きます。
なぜ交渉が攻撃面になるのか。TLS のようなプロトコルでは、クライアントが対応バージョンと暗号スイートの一覧を ClientHello で送り、サーバーが共通集合から一つを選んで返します。この一覧はまだ鍵が確立していない段階で平文として飛ぶため、経路上の MITM は中身を観測でき、書き換えもできます。交渉の原理と完全性保護の全体像は 暗号アジリティとプロトコルのバージョン交渉 で扱っており、本稿はそこで触れた個別攻撃を系譜として深掘りします。
ダウングレードには大きく二方向あります。(1) バージョンダウングレード:TLS 1.2 を SSLv3 や SSLv2 へ落とす(POODLE・DROWN)。(2) 暗号スイートダウングレード:強い鍵交換を輸出グレードの弱い鍵交換へ落とす(FREAK・Logjam)。どちらも「弱い候補を残す後方互換」と「交渉の非認証」という同じ二つの前提に依存します。前提を一つでも断てば、その攻撃面は消えます。
FREAK と Logjam:暗号スイートを輸出グレードへ落とす
1990 年代の米国は、暗号製品の輸出に鍵長制限を課しており、国外向けに鍵長を 512 ビット程度へ抑えた 輸出グレード(export-grade) スイートが規定されました。規制は後に撤廃されましたが、該当スイートのコードは何十年もサーバーとライブラリに残存し、2015 年に二つの攻撃として爆発しました。
FREAK(Factoring RSA Export Keys)は輸出グレードの RSA(RSA_EXPORT、512 ビット一時鍵)を標的にします。MITM はサーバーへの ClientHello、あるいはサーバー応答を細工し、サーバーに 512 ビットの一時 RSA 鍵を使わせ、クライアントに「これが正規のパラメータだ」と信じ込ませます。512 ビット合成数は当時すでに数時間規模で因数分解可能で、攻撃者は一時鍵の秘密成分を回復し、セッションを復号・改ざんできました。クライアント実装が「RSA_EXPORT を要求していないのに 512 ビット一時鍵を受け入れる」というバグを持っていたことが成立条件でした。
Logjam は同じ構図を Diffie-Hellman 鍵交換へ適用します。MITM が ClientHello を書き換えて DHE_EXPORT(512 ビット DH)をサーバーに選ばせます。DH のダウングレードが特に危険だったのは、多数のサーバーが同一の素数(共有 DH パラメータ)を使い回していた点です。攻撃者は一般数体ふるい(NFS)の重い前計算をその素数に対して一度だけ実行すれば、以後その素数を使う全セッションの離散対数を安価に解けます。前計算という重い投資を一度で全サーバーへ償却できる――これが Logjam の射程を広げました。
FREAK: MITM が 512bit RSA 一時鍵を強制 → 数時間で因数分解 → 鍵回復
Logjam: MITM が DHE_EXPORT(512bit DH) を強制
共有素数 p に NFS 前計算(一度だけ・高コスト)
→ 以後 p を使う全セッションの離散対数を安価に解く
TLS 1.2 の Finished メッセージはハンドシェイク全体のハッシュを確立鍵で計算するため、理屈上はダウングレードを検知できます。ところが FREAK・Logjam では交渉の結果として鍵自体が即座に破れるため、攻撃者は正しい Finished を計算し直せてしまいます。完全性チェックの強度は、それを支える鍵の強度を上限とします。弱い鍵を候補に残せば、後段の検証がいくら正しくても無力化される――ここが核心です。
DROWN:別プロトコルへの鍵流用(cross-protocol 攻撃)
DROWN(Decrypting RSA with Obsolete and Weakened eNcryption、2016)は、ダウングレードの中でも特に巧妙な cross-protocol 攻撃 です。標的は最新の TLS サーバーですが、攻撃の梃子は同じサーバーが別ポートでまだ有効にしていた SSLv2 にあります。
SSLv2 には Bleichenbacher 型のパディングオラクル(RSA PKCS#1 v1.5 の復号オラクル)として悪用できる構造欠陥があり、さらに輸出グレード暗号と組み合わさると、サーバーへ大量の細工クエリを投げることで RSA で暗号化された値を復号できます。決定的なのは、多くの運用で TLS と SSLv2 が同一の RSA 秘密鍵(同一証明書)を共有していた点です。攻撃者は被害者の最新 TLS セッション(RSA 鍵交換を使うもの)を記録し、その中の RSA 暗号文を、脆弱な SSLv2 サーバーを復号オラクルとして使い回して解読します。
被害者 --TLS(最新)--> サーバー # RSA 鍵交換の暗号文を MITM が記録
攻撃者 --SSLv2(脆弱)--> 同一鍵のサーバー # 記録した暗号文を復号する梃子に使う
前提: TLS と SSLv2 が同じ RSA 秘密鍵を共有
帰結: 「使っていないつもりの SSLv2」が現役 TLS を巻き添えに破る
つまり DROWN は、ユーザーが一度も SSLv2 を使わなくても成立します。サーバー側にその古いプロトコルが「有効なまま放置」されているだけで、現役の強い接続が巻き添えになる。これは「弱い方式を一つでも残すと、それが鍵を共有する強い方式まで連鎖的に汚染する」という、ダウングレード系の最も重要な教訓を端的に示します。対策は SSLv2 の完全無効化と、プロトコルをまたいだ秘密鍵の共有を断つことでした。Bleichenbacher 系オラクルの 1 ビットの漏れから復号へ至る機序は パディングオラクル攻撃 と同根です。
POODLE:バージョンを SSLv3 へ落としてから刺す
POODLE(Padding Oracle On Downgraded Legacy Encryption、2014)は、バージョンダウングレードと SSLv3 の構造欠陥を組み合わせた攻撃です。当時のブラウザは、TLS ハンドシェイクが失敗すると古いプロトコルへ自動的に再試行する「ダウングレードダンス」を実装していました。MITM は正規の TLS ハンドシェイクをわざと妨害(パケットを落とす)するだけで、TLS 1.2 対応の両端を SSLv3 へ後退させられます。
SSLv3 の CBC モードは MAC-then-Encrypt を採り、パディングについて末尾 1 バイト(パディング長)しか検証せず、残りのパディングバイトの中身は検証しない仕様でした。攻撃者はターゲットブロックの暗号文を末尾ブロックへコピーし、復号後の末尾バイトがちょうど期待するパディング長に一致すれば検証が通る確率 1/256 を利用して、HTTPS Cookie を 1 バイトずつ復号します。SSLv3 という退役間際の弱い方式へ落とせたからこそ、この構造欠陥が現実の実害に変わりました。POODLE と SSLv3 廃止の流れは 歴史的に破られたプロトコル分析 でも類型化しています。
POODLE の本質的な弱点は SSLv3 のパディングではなく、ハンドシェイク失敗を「弱い方式へ落ちる合図」として扱ったクライアント側の挙動です。MITM はパケットを一つ落とすだけで、暗号を一切破らずに両端を弱い世界へ移送できます。「失敗したら弱い方へフォールバックする」設計は、能動的な攻撃者にとって便利な自爆スイッチになります。安全な交渉は失敗時に弱い方へ落ちるのではなく、安全に中止するべきです。
ネゴシエーション完全性とダウングレード番兵
これらの攻撃が示す共通の急所は、交渉で何に合意したかが、鍵確立後に改ざんなしと確認できないことです。防御はネゴシエーション完全性を交渉に与えること――具体的には次の三つです。
第一に、弱い選択肢を規格から排除する。行き先が無ければダウングレードは成立しません。TLS 1.3 は輸出グレードスイート・静的 RSA 鍵交換・CBC を削除し、前方秘匿な (EC)DHE と AEAD のみを残しました。第二に、交渉全体を強い鍵と署名で事後認証する。TLS 1.3 のサーバーは CertificateVerify で、それまでの全ハンドシェイクのハッシュ(transcript hash)に署名します。MITM が交渉を 1 ビットでも書き換えれば署名検証が失敗し、署名鍵は証明書に紐づくため攻撃者は正しい署名を作れません。
第三が、明示的な ダウングレード番兵(sentinel) です。TLS 1.3 サーバーは、クライアントが旧バージョンへ落とされた状況を検知させるため、ServerHello.random の末尾 8 バイトに特定の固定値を埋め込みます。具体的には、TLS 1.2 で応答する際は 44 4F 57 4E 47 52 44 01、TLS 1.1 以下なら末尾を ...00 にした値を入れます。TLS 1.3 を理解するクライアントは、自分が 1.3 を提示したのに 1.2 以下の応答にこの番兵を見つけたら「ダウングレードされた」と判断して接続を中止します。番兵自体も transcript に含まれて署名で覆われるため、MITM が後から消すこともできません。
| 攻撃 | 年 | ダウングレードの種類 | 梃子にした弱点 |
|---|---|---|---|
| FREAK | 2015 | 暗号スイート(512bit RSA) | 輸出グレード一時鍵の受け入れバグ |
| Logjam | 2015 | 暗号スイート(512bit DH) | 共有素数 + NFS 前計算 |
| DROWN | 2016 | cross-protocol(SSLv2 流用) | 同一 RSA 鍵 + SSLv2 復号オラクル |
| POODLE | 2014 | バージョン(→ SSLv3) | CBC パディング非検証 + 自動フォールバック |
TLS 1.3 を使えない過渡期の対策が TLS_FALLBACK_SCSV です。クライアントが自発的にフォールバックして再接続する際、ダミーの暗号スイート識別子 TLS_FALLBACK_SCSV を一覧に追加します。これを見たサーバーは「クライアントは本来もっと高いバージョンを出せたのに落ちてきた」と判断し、自分がより高いバージョンに対応していれば接続を拒否します。POODLE の自動フォールバックを暗号学的にではなくシグナルで封じる、TLS 1.2 世代の応急処置でした。a < b のように弱い方へ静かに落ちる経路を、明示的なシグナルで可視化したと言えます。
(1) FREAK=512bit RSA 輸出鍵を強制、Logjam=512bit DH + 共有素数の NFS 前計算。(2) DROWN=SSLv2 を別ポートで温存し同一 RSA 鍵を共有したことで現役 TLS を巻き添え(cross-protocol)。(3) POODLE=SSLv3 へ自動フォールバック + CBC パディング非検証、対策は SSLv3 廃止と TLS_FALLBACK_SCSV。(4) TLS 1.3 の防御=弱い方式の排除 + transcript への CertificateVerify 署名 + ServerHello.random の番兵 44 4F 57 4E 47 52 44。共通の根本原因は「交渉が非認証」「弱い候補の温存」。
まとめ
ダウングレード攻撃の系譜は、暗号アルゴリズム自体の敗北史ではなく、交渉の管理を誤った歴史です。FREAK と Logjam は輸出グレードという弱い暗号スイートを強制し、DROWN は使っていないはずの SSLv2 を鍵共有経由で梃子にし、POODLE は自動フォールバックでバージョンを SSLv3 へ落としました。共通するのは「後方互換で弱い選択肢を残す」ことと「交渉が鍵確立後に認証されない」ことです。
対策の原則は明快です。弱い方式は候補から消し(行き先を断つ)、交渉全体を強い鍵と署名に拘束し(改ざんを検知)、ダウングレードされた事実を番兵で検知する。TLS 1.3 はこの三つを (EC)DHE 専用化・CertificateVerify による transcript 署名・ServerHello.random の番兵として実装し、ダウングレードを構造的に封じました。交渉と完全性の総論は 暗号アジリティとプロトコルのバージョン交渉、破綻の類型化は 歴史的に破られたプロトコル分析、CBC 由来のオラクル機序は パディングオラクル攻撃 を合わせて押さえてください。
セキュリティ Article
プロトコルダウングレードとバージョン交渉攻撃の系譜を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
ダウングレード攻撃
比較で見る軸
難易度: advanced / カテゴリ: セキュリティ / タグ数: 6
導入後に効く点
根本原因は交渉メッセージが鍵確立前に平文で飛び、後から認証されないこと。DROWN は同じ鍵を別プロトコルで使い回す cross-protocol 攻撃で、弱い方式を一つ残すだけで強い接続まで巻き添えになる。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- セキュリティ
- タグ数
- 6
判断チェックリスト
- 自社の用途が「ダウングレード攻撃 / TLS」に近いか確認する。
- 強みである「ダウングレード攻撃は MITM が交渉を細工し、両端を弱い暗号や旧バージョンへ引きずり下ろす手口。FREAK(512ビット RSA)・Logjam(512ビット DH)・DROWN(SSLv2 を別ポートで悪用)・POODLE(SSLv3 へ落とす)が代表例。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。