攻撃と防御 — 破る側の視点で守りを設計する

暗号は数式が正しいだけでは安全になりません。使い方・実装・運用の隙間を突かれて破られます。ここでは代表的な3つの攻撃 — 認証なき鍵交換への中間者攻撃、パスワードへの総当たり/辞書攻撃、実行時間の漏れを突くタイミング攻撃 — を動かしながら、それぞれの防御がなぜ効くのかを理解します。攻撃を学ぶのは、あくまで守りを設計するためです。

1. なぜ「破る側」の視点で学ぶのか

堅牢なシステムを作る人は、必ず攻撃者の頭で自分の設計を眺めます。「この鍵はどこから漏れうるか」「この比較処理は何を教えてしまうか」と問い続けることで、仕様書には現れない現実の攻撃面(attack surface)が見えてくるからです。防御を学ぶ最短路は、攻撃の原理を知ることにあります。

本章で扱うのは、いずれも原理の可視化です。実際に第三者のシステムへ仕掛けられる具体的な手順やツールは扱いません。攻撃の「かたち」を掴み、それを封じる設計思想を身につけるのが目的です。

POINT — 防御は「面」で考える(多層防御) ひとつの対策が破られても次が残るように、独立した防御を層状に重ねる考え方を多層防御(defense in depth)と呼ぶ。中間者攻撃には「証明書による認証」、パスワードには「ソルト+ストレッチング+レート制限」、タイミング攻撃には「定数時間実装」——攻撃ごとに効く層が違うからこそ、重ねることに意味がある。

2. 中間者攻撃 — 認証なき鍵交換の急所

DH鍵交換は、盗聴者がいても共有鍵を作れる魔法でした。しかしそれは「相手が本人かどうか」を何も保証しません。回線の途中に割り込んだ攻撃者(マロリー)が、アリスにもボブにも「自分が相手だ」と振る舞えば、両側と別々の鍵を結んでしまいます。これが中間者攻撃(MITM)です。

下のデモで「次のステップ」を進めてください。マロリーがアリス⇔マロリー間の鍵 K1 と、マロリー⇔ボブ間の鍵 K2 を別々に握り、中間ですべてを復号・再暗号化できてしまう様子が見えます。次に「証明書で公開鍵を認証」をONにすると、同じ攻撃が検知されてブロックされます。

中間者攻撃 — 認証の有無で結末がどう変わるか
左=アリス、中央=マロリー(攻撃者)、右=ボブ。認証OFFでは、マロリーが公開値をすり替え、両側と別の鍵を確立して中間で盗聴・改ざんし放題になる。認証ONでは、ボブの公開鍵に付いた認証局(CA)の署名をアリスが検証するため、すり替えた鍵は署名と一致せず、接続が中断される。
K = (ga)b = (gb)a = gab (mod p) DH自体は正しく共有鍵を作る。だが「その ga が本当にアリスのものか」は数式のどこにも書かれていない — そこを認証で埋める
POINT — 鍵交換に「認証」を接ぎ木する MITM を封じる鍵は公開鍵の真正性。TLSでは、サーバの公開鍵を認証局(CA)が署名した証明書で配り、クライアントは信頼するCAの公開鍵で署名を検証する(電子署名と証明書/TLSのしくみ)。署名は秘密鍵を持つ者にしか作れないので、マロリーは鍵をすり替えても正しい署名までは作れず、化けの皮が剥がれる。認証のないDHは、それ単体では中間者に無防備だと覚えておく。

3. パスワードという弱点 — 総当たりと辞書、そしてソルト

パスワードの強さは、素朴には総当たり(ブルートフォース)で試すべき候補の数で決まります。使える文字の種類を N、長さを L とすると、候補は NL 通り。これを情報量(エントロピー)で測ると L·log2N ビットです。1ビット増えるごとに解読コストは2倍になります。

下のデモで文字種と長さを変え、総当たり空間と推定解読時間がどう激変するかを見てください。「8文字の英数字」と「4単語のパスフレーズ」の比較、そして攻撃シナリオ(試行速度)による解読時間の差にも注目です。

パスワード強度 — 総当たり空間・辞書攻撃・ソルト&ストレッチング
棒は情報量(ビット)に比例。右端に推定解読時間(選んだ攻撃シナリオでの平均)を表示。ストレッチング(1回の照合をわざと遅くする)は試行速度そのものを叩き落とすため、同じパスワードでも解読時間が桁違いに伸びる。ソルトは下段の通り、同じパスワードでも保存ハッシュを別物にして事前計算表(レインボーテーブル)と一括攻撃を無効化する。
総当たり空間 = NL  エントロピー H = L · log2N  [bit] 解読時間の目安 ≈ (NL / 2) ÷ 試行速度。ストレッチングは分母を、長さ・文字種は分子を動かす
注意 — 長くても弱いパスワードがある(辞書攻撃) Password2024! は13文字あり、総当たりだけ考えれば強そうに見える。しかし攻撃者はまずよくある単語・人名・流出パスワード・年号・キーボード配列を並べた辞書から試す。辞書に載る語や「単語+数字」のありがちな組み合わせは、長さの割に候補数が桁違いに小さく、実質20ビット前後しかない。強さは長さだけでは決まらない — 予測できないことが本質。無関係な単語を並べた長いパスフレーズが強いのはこのためだ。

4. サイドチャネル — 時間が秘密を漏らす

暗号アルゴリズムが数学的に堅牢でも、それを走らせる物理的な実装が秘密を漏らすことがあります。実行時間・消費電力・電磁波・キャッシュの状態など、本来の入出力の「横(side)」から情報がにじみ出る経路をサイドチャネルと呼びます。

最も直感的なのがタイミング攻撃です。下は、パスワード(トークン)を1文字ずつ比較し、不一致を見つけた瞬間に処理を打ち切る脆弱な照合のトイモデル。合っている文字が多いほど照合に時間がかかるため、応答時間の差から正解の文字が1つずつ絞り込まれていきます(説明のため誇張・単純化したモデルです)。「定数時間比較」をONにすると、常に全文字を比較して時間差を消し、この漏れを塞ぎます。

タイミング攻撃の直感 — 応答時間から秘密が1文字ずつ漏れる(教育用の単純化モデル)
棒=各候補文字を試したときの平均応答時間(ノイズ入りの測定を多数回平均するとムラが消えて真の差が浮かぶ)。脆弱モデルでは、正解の文字だけ応答が「1段」長くなり、そこを選べば次の桁へ進める。定数時間比較ではすべての候補で時間が揃い、手がかりが消える(攻撃者は最初の桁で足止め)。
一歩先へ — 「横から漏れる」という発想 タイミングは氷山の一角。RSA復号のべき乗剰余に要する時間、AESのテーブル参照が起こすキャッシュの当たり外れ、暗号処理中の消費電力の波形、さらには誤り訂正が返すエラーメッセージの違い(パディングオラクル)まで、秘密は思わぬ経路から漏れる。だから現代の暗号実装は「入出力さえ正しければよい」では済まず、秘密に依存して実行時間・メモリアクセス・分岐を変えないという定数時間プログラミングを徹底する。数学の安全性と実装の安全性は別問題だ、というのがサイドチャネルの教訓。

5. まとめ — 多層防御と、越えてはならない一線

注意 — 自分のシステム以外への攻撃は犯罪 ここで学んだのは守りを設計するための原理であって、他者への攻撃手順ではない。許可なく他人のシステムやアカウントに侵入・総当たり・盗聴を試みる行為は、日本の不正アクセス禁止法をはじめ各国の法律で明確に犯罪とされている。攻撃技術の検証は、自分が所有する環境や、明示的な許可を得た範囲(バグバウンティ・ペネトレーションテストの契約下)でのみ行うこと。知識は防御のために使う。