前章で、TCPは信頼できない経路の上に信頼できる通信を築いた。だが、その通信は丸見えだった。パケットは無数のルーターを経由する。その途中で誰かが覗けば、あなたのパスワードもクレジットカード番号も、平文で読めてしまう。
ブラウザのURL欄にある錠前アイコン(HTTPS)は、この盗聴を防ぐ。だがここには、一見不可能な難題がある。盗聴されている通信路で、初対面のサーバーと、どうやって「二人だけの秘密の鍵」を共有するのか。 鍵そのものを送れば、盗聴者にも鍵が渡ってしまうのに。この章で、その魔法——TLS——を解く。
二つの暗号方式 — 歴史の必然
暗号には大きく二種類ある。まずその違いを押さえよう。
共通鍵暗号(対称鍵)は、暗号化と復号に同じ鍵を使う。速くて効率的だが、致命的な問題がある。どうやって相手に鍵を渡すのか。鍵を通信路で送れば、盗聴者にも鍵が渡る。かといって事前に会って手渡しするのは、地球の裏側のサーバーには不可能だ。これが鍵配送問題だ。
公開鍵暗号(非対称鍵)は、この問題を解く革命だった。ペアになった2つの鍵を使う。
- 公開鍵: 誰にでも配ってよい。これで暗号化する
- 秘密鍵: 本人だけが持つ。公開鍵で暗号化されたものは、対の秘密鍵でしか復号できない
公開鍵をばら撒いても、それで暗号化されたものは秘密鍵の持ち主しか読めない。「南京錠だけを配り、その鍵は自分だけが持つ」イメージだ。誰でも施錠(暗号化)できるが、開錠(復号)できるのは鍵の持ち主だけ。ただし公開鍵暗号は計算が重い。そこで実際のTLSは、両者を組み合わせる。
厨房のアナロジー — 鍵付きの受け渡しボックス
取引先と、レシピ(秘密の情報)をやり取りしたいとする。だが配達経路の途中に、内容を盗み見る者がいるかもしれない。
賢い方法はこうだ。まず取引先が、開いた状態の南京錠(公開鍵)だけを送ってくる。鍵本体(秘密鍵)は取引先が握ったままだ。あなたはレシピを箱に入れ、その南京錠で施錠して送り返す。施錠した箱は、途中で誰が奪っても開けられない。鍵を持つ取引先だけが開けられる。
そして本命はここからだ。この安全な箱を使って、あなたと取引先だけが知る「今日の合言葉(共通鍵)」を共有する。以降のやり取りは、軽くて速い合言葉方式(共通鍵暗号)で行う。「重い公開鍵は最初の鍵共有だけに使い、本番のデータは軽い共通鍵で」——これがTLSの基本戦略だ。
私が飲食店で機密のレシピや原価表を扱ったとき、鍵付きのボックスで受け渡しした経験に近い。中身そのものより、「鍵をどう安全に共有するか」が全ての要だった。
鍵交換 — 盗聴されても秘密を作る魔法
TLS 1.3の核心は、盗聴されている通信路で、二人だけの共通鍵を合成することだ。これを可能にするのがDiffie-Hellman鍵交換(DH)という、数学の美しいアイデアだ。
直感を「色の混合」で掴もう。混ぜた色から元の色を分離するのは極めて難しい、という一方向性を利用する。
アリス 公開でやり取り ボブ
秘密の色 a 秘密の色 b
│ 共通の色(公開) を両者が知っている │
▼ ▼
共通+a を混ぜる ────── 送信(盗聴されてもOK) ────▶ 受け取る
受け取る ◀──── 送信(盗聴されてもOK) ────── 共通+b を混ぜる
│ │
▼ ▼
(共通+b) に a を足す (共通+a) に b を足す
└────────────┐ ┌───────────────┘
▼ ▼
両者とも「共通+a+b」という同じ色に到達!
盗聴者は a も b も知らないので、この色を作れない
数学的には、大きな素数 と生成元 を公開し、各自が秘密の数 , を持つ。やり取りするのは と だけ。すると双方が同じ共通鍵に到達する:
盗聴者は と を見られるが、そこから や を逆算する(離散対数問題)のは、鍵が十分大きければ現実的な時間では解けない。だから盗聴者だけが を作れない。公開の場で、二人だけの秘密が生まれる。これが錠前アイコンの数学的な心臓部だ。
証明書 — 「本物の相手」だと証明する
鍵交換だけでは、まだ穴がある。あなたが鍵交換している相手は、本当に目的のサーバーか? 途中で攻撃者が「私が銀行です」と成りすまし、あなたと攻撃者、攻撃者と銀行で別々に鍵交換したら、通信は暗号化されていても攻撃者に筒抜けだ(中間者攻撃, MITM)。
これを防ぐのがサーバー証明書と、その裏にある公開鍵基盤(PKI)だ。
信頼の連鎖はこうなっている。認証局(CA)という、社会的に信頼された第三者が、「この公開鍵は確かに example.com のものだ」とデジタル署名して保証する。ブラウザは、あらかじめ信頼するCAの一覧(ルート証明書)を持っている。
信頼の連鎖(証明書チェーン):
ルートCA(ブラウザが最初から信頼)
│ 署名
▼
中間CA
│ 署名
▼
example.com のサーバー証明書(公開鍵を含む)
│
▼
ブラウザ: チェーンを辿り、信頼するルートCAに行き着けば「本物」と判定 ✓
デジタル署名は、公開鍵暗号を逆向きに使う。CAは自分の秘密鍵で署名し、誰もがCAの公開鍵で「確かにこのCAが署名した」と検証できる。秘密鍵を持つCAにしか作れない署名だから、偽造できない。「証明書エラー」の警告は、この信頼の連鎖が途切れた(自己署名、期限切れ、ドメイン不一致など)ときに出る。
TLS 1.3ハンドシェイク — 速さと安全の両立
TLS 1.3(2018年標準化)は、これらを組み合わせつつ、接続の高速化を実現した。旧来のTLS 1.2が2往復(2-RTT)を要したのに対し、1-RTTで暗号通信を始められる。
クライアント サーバー
│ │
│─ ClientHello ───────────────────────────▶│
│ + 鍵交換パラメータ(g^a) │ ①いきなり鍵材料を送る
│ + 対応する暗号方式の候補 │
│ │
│◀──────────── ServerHello ────────────────│
│ + 鍵交換パラメータ(g^b) │ ②鍵材料 + 証明書
│ + サーバー証明書 │
│ + {以降このデータは暗号化} │
│ │
│ この時点で両者とも共通鍵 g^(ab) を計算完了 │
│═══════ 1-RTTで暗号化データ通信開始 ════════│
TLS 1.3は、安全性の低い古い暗号方式(RSA鍵交換など)をきっぱり廃止し、選択肢を安全なものだけに絞った。「設定を間違えて弱い暗号を選ぶ」余地を設計から消したのだ。第13章のTCPハンドシェイクの上に、このTLSハンドシェイクが乗る。「HTTPSの最初のアクセスが少し待たされる」のは、この二段構えの握手のためだが、TLS 1.3の1-RTT化でそれも大きく短縮された。
前方秘匿性 — 未来の漏洩から過去を守る
TLS 1.3が必須としたもう一つの重要な性質が前方秘匿性(Forward Secrecy, PFS)だ。
想像してほしい。攻撃者が、あなたの暗号化通信をすべて記録しておく。そして何年も後、サーバーの秘密鍵を何らかの方法で盗んだとする。もし過去の通信がその秘密鍵で復号できてしまうなら、記録された過去の通信がすべて暴かれる。
前方秘匿性は、これを防ぐ。鍵交換のたびに使い捨ての一時的な鍵を生成し、セッション終了後は破棄する。だから、後でサーバーの長期秘密鍵が漏れても、過去の各セッションの共通鍵は復元できない。
これはDiffie-Hellmanの一時鍵(ephemeral、ECDHEの “E”)によって実現される。TLS 1.3では、この前方秘匿性が必須になった。「今は解読できないから記録しておいて後で解く」という攻撃(harvest now, decrypt later)への、設計レベルの防御だ。
まとめ — 「おまじない」の消し方
- 鍵配送問題こそ本質:共通鍵は速いが「鍵をどう渡すか」が難しい。公開鍵暗号がこれを解いた
- Diffie-Hellman鍵交換:盗聴される公開の場で、二人だけの共通鍵を数学的に合成する()
- 証明書とPKI:CAの署名で「本物の相手」を保証し、中間者による成りすましを防ぐ
- TLS 1.3は速く安全:1-RTTで暗号通信を開始し、弱い暗号方式を設計から排除した
- 前方秘匿性:使い捨ての鍵で、将来の鍵漏洩からも過去の通信を守る
「なぜ盗聴される通信路で秘密を守れるのか」「錠前アイコンは何を保証しているのか」——その答えは、公開鍵暗号と、信頼の連鎖という設計にあった。
これで通信は「信頼でき、かつ秘匿される」ようになった。だが、システムを複数のマシンに分散させると、新たな哲学的難問が現れる。「一貫性」と「可用性」は、両立しない。次章では、分散システムの根本原理——CAP定理と、あえて壊して学ぶカオスエンジニアリング——へ進む。
「完全な秘密とは、鍵を隠すことではない。鍵の作り方を、二人だけが知っていることだ。暗号技術の歴史は、『何を秘密にすべきか』を問い直し続けた歴史でもある。」