✍️ 필사 모드: TLS/SSL と PKI 完全攻略 — Handshake、Certificate Chain、Cipher Suite、0-RTT、そして Post-Quantum 時代 (2025)
日本語0. 錠前一つの重み
アドレスバーの左端にある小さな錠前。ユーザーはたいてい 2 秒も見ない。しかしその裏には:
- 1994 年の Netscape SSL 1.0 プロトタイプ。
- 1999 年の IETF TLS 1.0 標準化。
- 2014 年の Heartbleed、インターネット史上最悪のバグ。
- 2018 年の TLS 1.3 大改修。
- 2024 年に Chrome が Post-Quantum (Kyber) を実戦投入。
ブラウザが HTTPS 要求のたびに問う 3 つの質問 — 「初対面のサーバーを信じていいか」「誰かが盗聴していないか」「パケットが改ざんされていないか」 — その答えが TLS と PKI にある。
本稿ではその中身を開ける。錠前をクリックしたとき実際に何が起こっているのか、なぜ TLS 1.3 は 1.2 の 2 倍速いのか、なぜ Let's Encrypt が革命だったのか、そしてなぜ 2024 年に Post-Quantum 暗号を急いで配備するのか。
1. TLS が解決する 3 つの問題
1.1 Confidentiality — 盗聴防止
共有 WiFi で平文 HTTP は tcpdump 一発で読める。2010 年の Firesheep 拡張が Facebook セッションクッキーを簡単に盗めることを示し、HTTPS 普及を加速した。
解決: 対称暗号 (AES, ChaCha20-Poly1305) の共有鍵。
1.2 Integrity — 改ざん防止
MITM が「100 円送金」を「10000 円送金」に書き換える可能性。暗号化だけでは止められない。
解決: MAC あるいは AEAD (AES-GCM, ChaCha20-Poly1305)。
1.3 Authentication — 相手が誰か
「google.com」に接続したつもりが攻撃者のサーバーなら、暗号化も改ざん防止も無意味。
解決: X.509 Certificate + PKI。CA がサーバーの身元を保証する。
2. 非対称暗号 — 共有鍵なしで秘密を作る
2.1 初対面のジレンマ
初対面の二人が暗号通信するには共有鍵が要る。しかし平文で鍵を送れば盗聴される。
2.2 Diffie-Hellman (1976)
Diffie, Hellman, Merkle (2002 年 Turing 賞):
Alice Bob
public g, p (p は大きな素数)
a = random() b = random()
A = g^a mod p B = g^b mod p
send A →
← receive B
shared = B^a mod p shared = A^b mod p
= g^(ab) mod p = g^(ab) mod p
中間者は A, B を見られるが g^(ab) を計算するには a か b が必要 → 離散対数問題で古典計算では不可能。
2.3 RSA (1977)
公開鍵: (n, e) (n = p*q, p,q は秘密の素数)
秘密鍵: d (d*e ≡ 1 mod φ(n))
暗号化: c = m^e mod n
復号: m = c^d mod n
安全性は大数の素因数分解困難性に依存。
2.4 共存期
初期 TLS (1994〜2010) は RSA 鍵交換が主流。クライアントが pre-master secret をサーバー公開鍵で暗号化して送る。
問題: Forward Secrecy がない。サーバー秘密鍵が漏れれば過去の全通信が復号される。
2010 年以降 DHE/ECDHE (Ephemeral) へ移行。TLS 1.3 は RSA 鍵交換を完全削除、ECDHE のみ。
2.5 ECC — 少ないビットで同じ安全性
| 対称鍵ビット | RSA 鍵長 | ECC 鍵長 |
|---|---|---|
| 80 | 1024 | 160 |
| 128 | 3072 | 256 |
| 256 | 15360 | 512 |
ECC 256 は RSA 3072 相当。現代 TLS は ECC が標準。
3. TLS 1.2 Handshake — 2-RTT の舞
Client Server
│ ClientHello │
│────────────────────────────────→│
│ ServerHello │
│ Certificate │
│ ServerKeyExchange │
│ ServerHelloDone │
│←────────────────────────────────│
│ ClientKeyExchange │
│ ChangeCipherSpec │
│ Finished (encrypted) │
│────────────────────────────────→│
│ ChangeCipherSpec │
│ Finished (encrypted) │
│←────────────────────────────────│
│ Application Data (encrypted) │
データ送出前に 2 往復。RTT 100ms なら 200ms の純遅延。ページロード体感の大きな足かせ。
3.1 Cipher Suite の解読
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
ECDHE: 鍵交換。RSA: 認証。AES_128_GCM: AEAD 暗号。SHA256: MAC/PRF 用ハッシュ。
組み合わせが数百通り。「null cipher」「export-grade 40-bit」などの危険な組み合わせが残存 → FREAK、Logjam 攻撃の温床。
3.2 TLS 1.2 の弱点
- 2-RTT の遅さ。
- オプションが多すぎて誤設定の温床 (DH 512-bit で Logjam)。
- MAC-then-Encrypt の脆弱性 (Lucky 13, POODLE)。
- RSA 鍵交換は Forward Secrecy なし。
4. TLS 1.3 — 2018 年の大手術
4.1 設計思想
「安全でない選択肢を除去する。誤設定の余地をなくす。」
4.2 1-RTT Handshake
Client Server
│ ClientHello │
│ (key_share: ECDHE pub, │
│ supported_versions: [1.3]) │
│────────────────────────────────→│
│ ServerHello │
│ (key_share: ECDHE pub) │
│ { EncryptedExtensions, │
│ Certificate, │
│ CertificateVerify, │
│ Finished } │
│←────────────────────────────────│
│ { Finished } │
│ Application Data (encrypted) │
│────────────────────────────────→│
クライアントは ClientHello に ECDHE 公開鍵を推測で同梱。サーバーは証明書・Finished をまとめて返す。1 RTT で完了、TLS 1.2 比 2 倍速。
4.3 削除された機能
- RSA 鍵交換、CBC モード、Renegotiation、圧縮 (CRIME 対策)、MD5、SHA-1、弱い curve。
許可される Cipher Suite はたった 5 つ:
TLS_AES_128_GCM_SHA256
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_128_CCM_SHA256
TLS_AES_128_CCM_8_SHA256
構造的に誤設定しにくい。
4.4 0-RTT Resumption
以前のセッションがあれば、ClientHello にアプリケーションデータを同梱できる。モバイルアプリや SPA で体感差大。
4.5 0-RTT の Replay リスク
0-RTT データは Forward Secrecy がなく replay 可能。攻撃者が録画して再送 → サーバーが同じ要求を二度処理。
→ 冪等な要求 (GET) のみ許可。POST は別ポリシー。HTTP/3 はサーバー側で replay 検知ウィンドウを保持。
4.6 導入速度
2018 RFC 8446 標準化 → 2020 までに主要ブラウザ対応 → 2024 現在、HTTPS トラフィックの 90% 以上が TLS 1.3。
5. Certificate Chain — 初対面を信じる方法
5.1 チェーン構造
[Root CA: DigiCert Global Root CA] ← ブラウザ/OS に内蔵
│ (sign)
▼
[Intermediate CA: DigiCert TLS RSA SHA256 2020 CA1]
│ (sign)
▼
[End-entity: google.com] ← サーバーが提示
ブラウザは Intermediate 公開鍵で google.com を検証し、Root 公開鍵で Intermediate を検証、Root は既知の信頼 → チェーン完成。
5.2 X.509 の中身
Certificate:
Version: 3
Serial Number: 04:a2:...
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, O=DigiCert Inc, CN=DigiCert TLS RSA SHA256 2020 CA1
Validity:
Not Before: Jan 1 2025
Not After: Apr 1 2026
Subject: C=US, O=Google LLC, CN=*.google.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public Key: <2048 bits>
X509v3 Extensions:
Subject Alt Name: DNS:*.google.com, DNS:google.com, ...
Key Usage: Digital Signature, Key Encipherment
Extended Key Usage: TLS Web Server Authentication
Authority Information Access: OCSP - http://...
Certificate Policies: 2.23.140.1.2.2 (Organization Validated)
Signature: <Intermediate CA の署名>
5.3 CA 検証レベル
- DV (Domain Validation): ドメイン所有のみ確認。HTTPS の 90%。Let's Encrypt。
- OV (Organization Validation): 会社実在を手動確認。
- EV (Extended Validation): 法的実体を深く審査。緑バー表示は 2019 年以降ブラウザが廃止。
5.4 ルート信頼の源泉
Root CA はブラウザ/OS にハードコード:
- Windows/Edge: Microsoft Trust Store。
- macOS/Safari/iOS: Apple Root CA List。
- Firefox: Mozilla 独立リスト。
- Chrome: 2023 年から独自 Root Store へ移行中。
5.5 有名な CA 失敗例
- 2011 DigiNotar: ハックされて偽 google.com 証明書発行 → イラン政府が Gmail 盗聴。倒産。
- 2015 CNNIC: エジプトの会社に中間 CA を渡し任意ドメイン発行。一部ルート削除。
- 2017 Symantec: 長年のずさんな検証 → Google 主導で段階的 distrust。CA 部門を DigiCert に売却。
CA 一つの侵害でインターネット全体が危険 → 次の層へ。
6. Certificate Transparency — 監視の民主化
6.1 問題の再確認
CA が誤発行しても被害者は気づかない。
6.2 アイデア
「全ての新しい証明書を公開 append-only ログに記録する。」
CA が発行時に複数の CT ログサーバーへ提出。各ログは Merkle tree で保証。証明書に Signed Certificate Timestamp (SCT) を付与し、ブラウザが検証。2018 年以降 Chrome は全新規証明書に SCT を必須化。
6.3 効果
ドメイン所有者は crt.sh などで自分のドメインの発行履歴を確認できる。
6.4 crt.sh の副産物
自社ドメインを crt.sh で検索すると: 忘れた staging サブドメイン、g00gle.com のような偽装ドメイン、退職した外注が作ったサブドメインなどが見つかる。
7. Let's Encrypt — HTTPS の民主化 (2016)
7.1 2015 年以前
年間数十ドル + 手動更新 + 設置難易度 → HTTPS は全 Web の 30% のみ。
7.2 3 つの革新
- 無料 (Mozilla, EFF, Akamai, Cisco 等の寄付)。
- ACME による自動化、
certbot一行。 - 90 日の短寿命で自動更新を強制、漏洩時の被害最小化。
7.3 ACME プロトコル
1. アカウント作成 (公開鍵登録)
2. 注文: example.com の証明書を要求
3. Challenge:
- HTTP-01: http://example.com/.well-known/acme-challenge/TOKEN に値配置
- DNS-01: _acme-challenge.example.com TXT に値設定
4. サーバーが Challenge を検証
5. CSR 提出 → 証明書発行
7.4 数字
2024 年時点で約 4 億件の有効証明書。HTTPS 世界普及率 90% 超の決定打。
7.5 後発組
ZeroSSL、Buypass、AWS Certificate Manager、Cloudflare や Fastly の統合発行。
8. 証明書失効 — 未解決の難題
8.1 なぜ難しいか
有効期間内に秘密鍵が漏洩したら失効が必要。しかしブラウザ全員にどう伝えるか。
8.2 CRL
CA が失効リストを公開。巨大化し、毎回 DL は非現実的。ブラウザはほぼ見ない。
8.3 OCSP
接続毎に CA に照会。問題: プライバシー漏洩 (CA がアクセス先を把握)、Fail-open vs Fail-closed のジレンマ (多くが fail-open = 実質無意味)、追加 RTT。
8.4 OCSP Stapling
サーバーが OCSP 応答を定期取得し Handshake に同梱。プライバシーも RTT も解決。だが普及は限定的。
8.5 Push 型が実態
Chrome の CRLSet、Firefox の OneCRL。Google/Mozilla が選定した緊急失効のみ配布。実際に機能しているのはこれ。
8.6 短寿命が現実解
失効が不完全なので頻繁に更新する。Let's Encrypt の 90 日、Apple は 2022 年に TLS 証明書最大寿命を 398 日に制限。
9. HSTS, HPKP, CAA — 追加の防御層
9.1 HSTS
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
意味: 今後 1 年、このホストに絶対 HTTP で接続しない。preload は Chrome 内蔵リストに登録されブラウザ出荷時から知られる。
9.2 HPKP の失敗
Public Key Pinning は誤設定でサイトを永久停止させ得る。危険すぎて 2018 年に Chrome が廃止。CT が同じ問題をより安全に解決。
9.3 CAA
DNS レコードで発行可能 CA を制限:
example.com. CAA 0 issue "letsencrypt.org"
2017 年以降 CA は CAA 尊重を義務化。誤/悪性発行を防ぐ。
10. TLS 攻撃史
10.1 Heartbleed (2014)
OpenSSL heartbeat のバグ。「16 バイト送ったから返せ」と言いつつ 1 バイトしか送らない → サーバーメモリ 16 バイトを漏出。秘密鍵・セッション・パスワード流出。「インターネット史上最悪のバグ」。Linux Foundation Core Infrastructure Initiative 誕生の契機。
10.2 BEAST, POODLE, Lucky 13
CBC モードのパディング攻撃群。AEAD (GCM) への移行を加速。
10.3 FREAK, Logjam (2015)
1990 年代米国輸出規制の名残である 512-bit export 鍵交換への強制ダウングレード。15 年後に攻撃ベクトルとして復活。教訓: 旧モード互換を残すと攻撃者がそこへ降格させる。TLS 1.3 が過激に旧機能を削除した理由。
10.4 DROWN, Sweet32 (2016)
SSLv2 や 3DES 等レガシー暗号を悪用し現代接続を攻撃。
10.5 Raccoon, ALPACA (2020-2021)
TLS 1.2 最後の世代の攻撃。TLS 1.3 は影響なし。アップグレード動機。
11. Post-Quantum 暗号 — 2024 年の急務
11.1 Harvest Now, Decrypt Later
量子コンピュータが 2030 年代に実用化されれば、Shor のアルゴリズムで RSA・ECC は共に破られる。攻撃者は今トラフィックを録画し、量子計算機出現後に復号可能。30 年秘匿が必要なデータ (医療記録、国家機密) は今すぐ量子耐性が必要。
11.2 NIST PQC 標準化 (2024)
- ML-KEM (Kyber): Key encapsulation、RSA/ECDHE 代替。
- ML-DSA (Dilithium): 署名、ECDSA 代替。
- SLH-DSA (SPHINCS+): ハッシュベース署名。
主力は格子ベース (lattice-based)。量子計算機でも困難と期待される問題。
11.3 ハイブリッド方式
従来 ECDH と新 Kyber を同時に使用 → 両方破らねば復号不能。段階移行戦略:
key = HKDF(ECDH(x25519) || Kyber768)
11.4 Chrome の配備 (2024)
2024 年 8 月 Chrome 116+ が TLS に X25519Kyber768 ハイブリッドをデフォルト有効化:
- Handshake サイズ増 (Kyber 公開鍵 1.2KB)。
- 約 1ms の追加 CPU。
- 一部ミドルボックス非互換で「post-quantum bytes too large」エラー → 一時ロールバック。
Cloudflare、AWS も同時期に導入。TLS 史上最大級の変化。
11.5 残る課題
- 署名アルゴリズム移行はより遅い (Dilithium 署名は 3〜5KB)。
- IoT 機器の Kyber 実装負担。
- Certificate Chain サイズが数十 KB へ増大。
- PKI 全体 (Root CA、証明書、CRL) の量子安全化は数年がかり。
12. 実務 TLS — チェックリスト
12.1 nginx 設定例
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:...;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 valid=300s;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
12.2 診断ツール
- SSL Labs (A+ を目標)。
- testssl.sh でローカル詳細解析。
- Hardenize で DNS/メール/Web 総合チェック。
- Chrome DevTools Security タブ。
12.3 性能チューニング
- OCSP Stapling 必ず有効化。
- HTTP/2 または HTTP/3 + TLS 1.3。
- Session Resumption (ID または ticket)、TLS 1.3 なら 0-RTT。
- ECDSA 証明書で CPU 節約。
12.4 監視
- 証明書失効 30 日前アラート必須。
- CT ログ監視 (crt.sh Watchtower、Cert Spotter)。
- TLS バージョン使用統計で古いクライアント把握。
13. 結び — 錠前が語ること
1994 年 Netscape SSL 1.0 から始まった旅路:
- プロトコル簡素化: 数百の cipher → 5 つ。
- 自動化: 手動発行 → ACME。
- 透明性: ブラックボックス CA → CT 公開ログ。
- 速度: 2-RTT → 1-RTT → 0-RTT。
- 経済: 有料 → 無料。
- 安全: 攻撃のフィードバックループ。
2024 年、量子計算機という全く新しい脅威により全スタックが再び動き始めた。30 年かけて築かれたインフラが今後 10 年で量子安全に再構築される。
錠前アイコン一つの裏にこの全歴史がある。HTTPS 接続のたびに数十人の数学者、エンジニア、標準化委員の仕事が同時に動く。
参考資料
- RFC 8446 — TLS 1.3。
- RFC 8555 — ACME。
- Ivan Ristic, "Bulletproof SSL and TLS" (Feisty Duck, 2022)。
- Eric Rescorla, "SSL and TLS: Designing and Building Secure Systems"。
- NIST FIPS 203/204/205 (ML-KEM, ML-DSA, SLH-DSA)。
- Cloudflare blog — TLS 1.3、Post-Quantum シリーズ。
- Mozilla Server Side TLS Guidelines。
- Let's Encrypt エンジニアリングブログ。
- crt.sh。
- SSL Labs Best Practices。
현재 단락 (1/223)
アドレスバーの左端にある小さな錠前。ユーザーはたいてい 2 秒も見ない。しかしその裏には: