TLS

TLS(Transport Layer Security)完全ガイド

はじめに

TLS(Transport Layer Security)は、インターネット上の通信を暗号化し、データの機密性、完全性、および認証を提供するプロトコルである。Webブラウジング(HTTPS)、メール(SMTPS/IMAPS)、VPN、VoIPなど、あらゆるネットワーク通信のセキュリティ基盤として広く使用されている。

TLSはSSL(Secure Sockets Layer)の後継プロトコルであり、Netscape社が1994年に開発したSSL 2.0から始まり、SSL 3.0を経て、1999年にIETFによりTLS 1.0(RFC 2246)として標準化された。最新のTLS 1.3(RFC 8446)は2018年に公開され、セキュリティの強化とパフォーマンスの改善が行われた。

本記事では、TLSの基本概念から暗号技術の基礎、ハンドシェイクプロトコル、証明書管理、パフォーマンス最適化、セキュリティベストプラクティス、そしてTLS 1.3の最新仕様まで、TLSの全容を体系的に解説する。


第1章: TLSの基本概念とプロトコルスタック

1.1 TLSの位置づけ

TLSはOSI参照モデルのトランスポート層(第4層)とアプリケーション層(第7層)の間に位置する。正確にはセッション層(第5層)とプレゼンテーション層(第6層)に相当する。

アプリケーション層    HTTP, SMTP, FTP, IMAP ...
─────────────────────────────────────────────
TLS                  暗号化・認証・完全性
─────────────────────────────────────────────
トランスポート層      TCP
─────────────────────────────────────────────
ネットワーク層        IP
─────────────────────────────────────────────
データリンク層        Ethernet, Wi-Fi

1.2 TLSの3つの主要機能

機能説明実現手段
機密性(Confidentiality)通信内容を第三者に読み取られないようにする対称暗号(AES-GCM等)
完全性(Integrity)通信内容が改ざんされていないことを保証MAC(HMAC, AEAD)
認証(Authentication)通信相手が正当であることを確認デジタル証明書(X.509)

1.3 TLSバージョンの歴史

バージョンRFC状態
SSL 1.0-1994未公開(重大な欠陥)
SSL 2.0-1995非推奨(RFC 6176で禁止)
SSL 3.0RFC 61011996非推奨(POODLE攻撃、RFC 7568で禁止)
TLS 1.0RFC 22461999非推奨(RFC 8996で禁止)
TLS 1.1RFC 43462006非推奨(RFC 8996で禁止)
TLS 1.2RFC 52462008現在も広く使用されている
TLS 1.3RFC 84462018最新の推奨バージョン

1.4 TLSプロトコルの構造

TLSは2つの主要な層で構成される:

┌──────────┬──────────────┬──────────┬──────────────┐
│Handshake │ Change Cipher│  Alert   │ Application  │
│ Protocol │ Spec Protocol│ Protocol │ Data Protocol│
├──────────┴──────────────┴──────────┴──────────────┤
│              TLS Record Protocol                    │
├─────────────────────────────────────────────────────┤
│                     TCP                              │
└─────────────────────────────────────────────────────┘

TLS Record Protocol(レコードプロトコル):

  • 上位プロトコルのデータをフラグメント化
  • 圧縮(TLS 1.3では廃止)
  • MAC(メッセージ認証コード)の付加またはAEAD暗号化
  • 暗号化
  • TCPへの送信

上位プロトコル:

  • Handshake Protocol: 暗号パラメータの交渉、認証
  • Change Cipher Spec Protocol: 暗号仕様の切り替え通知(TLS 1.3では廃止)
  • Alert Protocol: エラーや警告の通知
  • Application Data Protocol: アプリケーションデータの転送

1.5 TLSレコードの構造

 0                   1                   2
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Content Type  |    Version    |    Length     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                               |
|            Fragment (payload)                  |
|                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
フィールドサイズ説明
Content Type1バイト20=ChangeCipherSpec, 21=Alert, 22=Handshake, 23=ApplicationData
Version2バイトTLS 1.0=0x0301, TLS 1.2=0x0303, TLS 1.3=0x0303
Length2バイトフラグメントの長さ(最大16384バイト = 2^14)
Fragment可変ペイロードデータ

注意: TLS 1.3では、互換性のためレコードのバージョンフィールドは0x0303(TLS 1.2)のままとなる。実際のバージョンはHandshakeのsupported_versions拡張で交渉される。

第2章: 暗号技術の基礎

TLSを理解するためには、その基盤となる暗号技術を理解する必要がある。

2.1 対称暗号(Symmetric Encryption)

同じ鍵で暗号化と復号を行う方式。高速だが、鍵の安全な共有が課題。

AES(Advanced Encryption Standard)

現在最も広く使用されているブロック暗号。128ビットのブロックサイズを持ち、鍵長は128/192/256ビット。

TLSで使用される暗号利用モード:

モード説明TLSバージョン
CBC(Cipher Block Chaining)ブロック連鎖方式TLS 1.0-1.2(非推奨)
GCM(Galois/Counter Mode)認証付き暗号(AEAD)TLS 1.2-1.3(推奨)
CCM(Counter with CBC-MAC)認証付き暗号(AEAD)TLS 1.2-1.3

ChaCha20-Poly1305

Googleが開発したストリーム暗号(ChaCha20)とMAC(Poly1305)の組み合わせ。AES-NIハードウェアアクセラレーションが利用できない環境(モバイルデバイスなど)で高いパフォーマンスを発揮する。

AES-GCM vs ChaCha20-Poly1305:
  - AES-GCM: AES-NIサポートのあるCPUで高速
  - ChaCha20-Poly1305: ソフトウェア実装で高速、サイドチャネル攻撃に強い

2.2 AEAD(Authenticated Encryption with Associated Data)

暗号化と認証を同時に行う方式。TLS 1.3ではAEAD暗号のみが使用可能。

AEAD暗号化:
  入力: 平文 + 関連データ(AAD)+ 鍵 + ノンス(IV)
  出力: 暗号文 + 認証タグ

  関連データ(AAD): 暗号化はされないが、認証の対象となるデータ
  (例: TLSレコードヘッダ)

TLS 1.3で許可されるAEAD暗号スイート:

  • 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

2.3 公開鍵暗号(Asymmetric Encryption)

異なる2つの鍵(公開鍵と秘密鍵)を使用する方式。鍵の共有問題を解決するが、対称暗号に比べて計算コストが高い。

RSA(Rivest-Shamir-Adleman)

大きな整数の素因数分解の困難性に基づく。鍵交換と電子署名の両方に使用可能。

RSA鍵長の推奨:
  - 2048ビット: 最低限の推奨(2030年まで)
  - 3072ビット: 中程度のセキュリティ
  - 4096ビット: 高セキュリティ

注意: TLS 1.3ではRSA鍵交換は廃止された(前方秘匿性がないため)
      RSA署名は引き続き使用可能

ECDSA(Elliptic Curve Digital Signature Algorithm)

楕円曲線暗号に基づく電子署名アルゴリズム。RSAと同等のセキュリティをより短い鍵長で実現。

鍵長の比較:
  RSA 2048ビット ≈ ECDSA 224ビット(secp224r1)
  RSA 3072ビット ≈ ECDSA 256ビット(secp256r1/P-256)
  RSA 7680ビット ≈ ECDSA 384ビット(secp384r1/P-384)
  RSA 15360ビット ≈ ECDSA 521ビット(secp521r1/P-521)

EdDSA(Edwards-curve Digital Signature Algorithm)

Twisted Edwardsカーブに基づく高速な電子署名アルゴリズム。Ed25519(Curve25519ベース)が広く使用されている。

2.4 鍵交換(Key Exchange)

TLSハンドシェイクで対称暗号の鍵(セッション鍵)を安全に共有するためのメカニズム。

Diffie-Hellman鍵交換(DH)

アリス(クライアント)          ボブ(サーバー)
  a = ランダムな秘密値           b = ランダムな秘密値
  A = g^a mod p                 B = g^b mod p
       │                             │
       │  ← g, p, A →               │
       │  ← B →                     │
       │                             │
  共有秘密 = B^a mod p          共有秘密 = A^b mod p
           = g^(ab) mod p                = g^(ab) mod p

ECDHE(Elliptic Curve Diffie-Hellman Ephemeral)

楕円曲線上のDiffie-Hellman鍵交換。一時的な鍵を使用するため、前方秘匿性(Forward Secrecy)を提供する。

TLS 1.3で使用される名前付き曲線:

  • x25519: 高速、安全、推奨(Daniel J. Bernstein設計)
  • secp256r1(P-256): NIST標準、広く使用
  • secp384r1(P-384): より高いセキュリティ
  • x448: 高セキュリティ
前方秘匿性(Forward Secrecy / PFS):
  - 一時的な鍵(Ephemeral Key)を各セッションで生成
  - サーバーの長期秘密鍵が漏洩しても、過去のセッションは解読不可
  - TLS 1.3では前方秘匿性が必須
  
  非PFS(RSA鍵交換、TLS 1.2以前):
    サーバーの秘密鍵が漏洩 → 過去のすべてのセッションが解読可能
  
  PFS(ECDHE鍵交換):
    サーバーの秘密鍵が漏洩 → 過去のセッションは安全

2.5 ハッシュ関数

任意の長さのデータから固定長のハッシュ値を生成する一方向関数。

アルゴリズム出力長TLSでの使用
MD5128ビット非推奨(衝突攻撃可能)
SHA-1160ビット非推奨(衝突攻撃実証済み)
SHA-256256ビットTLS 1.2/1.3で使用
SHA-384384ビットTLS 1.2/1.3で使用

2.6 HMAC(Hash-based Message Authentication Code)

ハッシュ関数と秘密鍵を使用してメッセージ認証コードを生成する。

HMAC(K, m) = H((K' ⊕ opad) || H((K' ⊕ ipad) || m))

K: 秘密鍵
m: メッセージ
H: ハッシュ関数
opad: 0x5c5c5c...
ipad: 0x363636...

2.7 HKDF(HMAC-based Key Derivation Function)

TLS 1.3で使用される鍵導出関数。マスターシークレットから複数の暗号鍵を安全に導出する。

HKDF-Extract(salt, IKM) → PRK
  salt: ソルト値
  IKM: 入力鍵材料(Input Keying Material)
  PRK: 擬似ランダム鍵(Pseudorandom Key)

HKDF-Expand(PRK, info, L) → OKM
  PRK: 擬似ランダム鍵
  info: コンテキスト情報
  L: 出力長
  OKM: 出力鍵材料(Output Keying Material)

第3章: TLS 1.2 ハンドシェイク

3.1 フルハンドシェイク(ECDHE鍵交換)

クライアント                                サーバー
    │                                          │
    │  ① ClientHello                          │
    │  (バージョン, ランダム値,                  │
    │   暗号スイート一覧,                       │
    │   圧縮方式, 拡張)                         │
    │─────────────────────────────────────────>│
    │                                          │
    │  ② ServerHello                          │
    │  (選択されたバージョン, ランダム値,         │
    │   選択された暗号スイート)                  │
    │<─────────────────────────────────────────│
    │                                          │
    │  ③ Certificate                          │
    │  (サーバー証明書チェーン)                  │
    │<─────────────────────────────────────────│
    │                                          │
    │  ④ ServerKeyExchange                    │
    │  (ECDHEパラメータ + 署名)                 │
    │<─────────────────────────────────────────│
    │                                          │
    │  ⑤ ServerHelloDone                      │
    │<─────────────────────────────────────────│
    │                                          │
    │  ⑥ ClientKeyExchange                    │
    │  (クライアントのECDH公開値)               │
    │─────────────────────────────────────────>│
    │                                          │
    │  ⑦ ChangeCipherSpec                     │
    │─────────────────────────────────────────>│
    │                                          │
    │  ⑧ Finished                             │
    │  (ハンドシェイクの検証値)                  │
    │─────────────────────────────────────────>│
    │                                          │
    │  ⑨ ChangeCipherSpec                     │
    │<─────────────────────────────────────────│
    │                                          │
    │  ⑩ Finished                             │
    │<─────────────────────────────────────────│
    │                                          │
    │  ===== 暗号化通信開始 =====               │
    │  Application Data ◄──────────────────►   │

ハンドシェイクに必要なRTT: 2 RTT

3.2 各メッセージの詳細

ClientHello

ClientHello {
    client_version: TLS 1.2 (0x0303)
    random: 32バイトのランダム値(タイムスタンプ4バイト + ランダム28バイト)
    session_id: セッション再開用ID(空の場合は新規接続)
    cipher_suites: [
        TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,      // 0xC02F
        TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,      // 0xC030
        TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,    // 0xC02B
        TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,    // 0xC02C
        TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, // 0xCCA8
        ...
    ]
    compression_methods: [null (0x00)]
    extensions: [
        server_name (SNI): "www.example.com",
        supported_groups: [x25519, secp256r1, secp384r1],
        signature_algorithms: [rsa_pss_rsae_sha256, ecdsa_secp256r1_sha256, ...],
        ec_point_formats: [uncompressed],
        ...
    ]
}

暗号スイートの命名規則(TLS 1.2)

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
 │    │     │         │   │   │    │
 │    │     │         │   │   │    └─ PRFのハッシュ: SHA-256
 │    │     │         │   │   └────── 暗号モード: GCM(AEAD)
 │    │     │         │   └────────── 鍵長: 128ビット
 │    │     │         └────────────── 対称暗号: AES
 │    │     └──────────────────────── 認証: RSA証明書
 │    └────────────────────────────── 鍵交換: ECDHE
 └─────────────────────────────────── プロトコル: TLS

ServerKeyExchange(ECDHE)

ServerKeyExchange {
    curve_type: named_curve (0x03)
    named_curve: x25519 (0x001D) or secp256r1 (0x0017)
    public_key: サーバーの一時ECDH公開鍵
    signature: 上記パラメータに対するサーバーの署名
}

3.3 鍵の導出(TLS 1.2)

プリマスターシークレット(ECDHE共有秘密)
        │
        ▼
マスターシークレット = PRF(pre_master_secret,
                          "master secret",
                          client_random + server_random)
        │
        ▼
鍵ブロック = PRF(master_secret,
                 "key expansion",
                 server_random + client_random)
        │
        ├── client_write_MAC_key
        ├── server_write_MAC_key
        ├── client_write_key(暗号化鍵)
        ├── server_write_key(暗号化鍵)
        ├── client_write_IV
        └── server_write_IV

3.4 セッション再開(Session Resumption)

Session ID方式

初回接続:
  ClientHello (session_id = 空) → ServerHello (session_id = ABC123)
  → フルハンドシェイク

再接続:
  ClientHello (session_id = ABC123)
  → ServerHello (session_id = ABC123)  ← サーバーがIDを認識
  → ChangeCipherSpec + Finished(双方)
  
  ハンドシェイク: 1 RTT(フルハンドシェイクの半分)

Session Ticket方式(RFC 5077)

初回接続:
  フルハンドシェイク
  → サーバーがNewSessionTicket(暗号化されたセッション情報)を送信
  → クライアントがチケットを保存

再接続:
  ClientHello (session_ticket拡張 = チケットデータ)
  → サーバーがチケットを復号してセッション情報を復元
  → 省略ハンドシェイク(1 RTT)
# OpenSSLでセッション再開の確認
$ openssl s_client -connect www.example.com:443 -reconnect -sess_out /tmp/session.pem

# セッションチケットの確認
$ openssl s_client -connect www.example.com:443 -tlsextdebug 2>&1 | grep -i ticket

3.5 SNI(Server Name Indication)

1つのIPアドレスで複数のTLSサイトをホスティングするための拡張。ClientHelloにサーバー名を含めることで、サーバーが適切な証明書を選択できる。

ClientHello {
    extensions: {
        server_name: [{
            name_type: host_name (0),
            host_name: "www.example.com"
        }]
    }
}

注意: SNIは平文で送信されるため、接続先のホスト名は盗聴可能。この問題を解決するために、Encrypted Client Hello(ECH、旧ESNI)が提案されている。

# SNIの確認
$ openssl s_client -connect 192.168.1.100:443 -servername www.example.com

# SNI無しの場合(デフォルト証明書が返される)
$ openssl s_client -connect 192.168.1.100:443 -noservername

第4章: TLS 1.3 ハンドシェイク

4.1 TLS 1.3の主要な変更点

TLS 1.3はTLS 1.2から大幅に改善されている:

項目TLS 1.2TLS 1.3
ハンドシェイクRTT2 RTT1 RTT(0-RTT再開も可能)
鍵交換RSA, DHE, ECDHEECDHEのみ(前方秘匿性必須)
対称暗号CBC, GCM, CCMAEADのみ(GCM, CCM, ChaCha20)
ハッシュMD5, SHA-1, SHA-256...SHA-256以上のみ
圧縮対応廃止
再ネゴシエーション対応廃止
ChangeCipherSpec使用廃止(互換性のためダミーは送信可)
暗号化開始タイミングFinished後ServerHello直後
0-RTTなし対応(Early Data)

4.2 TLS 1.3 フルハンドシェイク(1-RTT)

クライアント                                サーバー
    │                                          │
    │  ① ClientHello                          │
    │  + key_share(ECDHE公開鍵)              │
    │  + supported_versions(TLS 1.3)         │
    │  + signature_algorithms                   │
    │  + psk_key_exchange_modes                 │
    │─────────────────────────────────────────>│
    │                                          │
    │  ② ServerHello                          │
    │  + key_share(ECDHE公開鍵)              │
    │  + supported_versions(TLS 1.3)         │
    │<─────────────────────────────────────────│
    │                                          │
    │  ───── 以降、暗号化 ─────                 │
    │                                          │
    │  ③ EncryptedExtensions                  │
    │<─────────────────────────────────────────│
    │                                          │
    │  ④ CertificateRequest(オプション)      │
    │<─────────────────────────────────────────│
    │                                          │
    │  ⑤ Certificate                          │
    │<─────────────────────────────────────────│
    │                                          │
    │  ⑥ CertificateVerify                    │
    │  (証明書の秘密鍵による署名)              │
    │<─────────────────────────────────────────│
    │                                          │
    │  ⑦ Finished                             │
    │<─────────────────────────────────────────│
    │                                          │
    │  ⑧ Certificate(クライアント認証時)      │
    │─────────────────────────────────────────>│
    │                                          │
    │  ⑨ CertificateVerify(クライアント認証時)│
    │─────────────────────────────────────────>│
    │                                          │
    │  ⑩ Finished                             │
    │─────────────────────────────────────────>│
    │                                          │
    │  ===== 暗号化通信開始 =====               │

ハンドシェイクに必要なRTT: 1 RTT

4.3 TLS 1.3のハンドシェイクが1 RTTである理由

TLS 1.2では、サーバーが暗号スイートを選択した後にECDHEパラメータを送信していた。TLS 1.3では:

  1. クライアントがClientHelloに推測したECDHE公開鍵を含める(key_share拡張)
  2. サーバーが即座に鍵交換を完了できる
  3. ServerHello直後から暗号化通信が可能
TLS 1.2:
  RTT 1: ClientHello → ServerHello + Certificate + ServerKeyExchange + ServerHelloDone
  RTT 2: ClientKeyExchange + ChangeCipherSpec + Finished → ChangeCipherSpec + Finished
  合計: 2 RTT

TLS 1.3:
  RTT 1: ClientHello(+key_share) → ServerHello(+key_share) + {暗号化データ} + Finished
         Finished →
  合計: 1 RTT

4.4 TLS 1.3 暗号スイート

TLS 1.3では暗号スイートの命名規則が簡略化された。鍵交換と署名アルゴリズムはスイートに含まれず、拡張で個別に交渉される。

TLS 1.3の暗号スイート(AEAD + ハッシュのみ):
  TLS_AES_128_GCM_SHA256         (0x1301)  ← 必須実装
  TLS_AES_256_GCM_SHA384         (0x1302)
  TLS_CHACHA20_POLY1305_SHA256   (0x1303)
  TLS_AES_128_CCM_SHA256         (0x1304)
  TLS_AES_128_CCM_8_SHA256       (0x1305)

鍵交換は supported_groups 拡張で交渉:
  x25519, secp256r1, secp384r1, x448, ...

署名は signature_algorithms 拡張で交渉:
  rsa_pss_rsae_sha256, ecdsa_secp256r1_sha256, ed25519, ...

4.5 TLS 1.3 鍵スケジュール

TLS 1.3の鍵導出はHKDFベースの構造化された鍵スケジュールに従う。

             0
             │
             ▼
   PSK ──> HKDF-Extract = Early Secret
             │
             ├── Derive-Secret(., "ext binder" | "res binder", "")
             │                  = binder_key
             ├── Derive-Secret(., "c e traffic", ClientHello)
             │                  = client_early_traffic_secret
             └── Derive-Secret(., "e exp master", ClientHello)
                                = early_exporter_master_secret
             │
             ▼
   (EC)DHE -> HKDF-Extract = Handshake Secret
             │
             ├── Derive-Secret(., "c hs traffic", ClientHello...ServerHello)
             │                  = client_handshake_traffic_secret
             └── Derive-Secret(., "s hs traffic", ClientHello...ServerHello)
                                = server_handshake_traffic_secret
             │
             ▼
   0 ──────> HKDF-Extract = Master Secret
             │
             ├── Derive-Secret(., "c ap traffic", ClientHello...server Finished)
             │                  = client_application_traffic_secret_0
             ├── Derive-Secret(., "s ap traffic", ClientHello...server Finished)
             │                  = server_application_traffic_secret_0
             ├── Derive-Secret(., "exp master", ClientHello...server Finished)
             │                  = exporter_master_secret
             └── Derive-Secret(., "res master", ClientHello...client Finished)
                                = resumption_master_secret

4.6 0-RTT(Early Data)

TLS 1.3では、前回の接続で取得したPSK(Pre-Shared Key)を使用して、最初のClientHelloと同時にアプリケーションデータを送信できる。

クライアント                                サーバー
    │                                          │
    │  ClientHello                             │
    │  + early_data                            │
    │  + key_share                             │
    │  + psk_identity                          │
    │─────────────────────────────────────────>│
    │  [Early Data(0-RTT)]                   │
    │═════════════════════════════════════════>│  ← 暗号化データ(0-RTT)
    │                                          │
    │  ServerHello                             │
    │  + pre_shared_key                        │
    │<─────────────────────────────────────────│
    │  {EncryptedExtensions}                   │
    │  {Finished}                              │
    │<─────────────────────────────────────────│
    │                                          │
    │  {Finished}                              │
    │─────────────────────────────────────────>│
    │                                          │
    │  ===== 1-RTTデータ =====                 │

0-RTTのセキュリティ上の注意点:

  • リプレイ攻撃に脆弱: 0-RTTデータは前方秘匿性を持たず、リプレイ可能
  • 冪等(idempotent)なリクエストのみに使用すべき: GETリクエストなど
  • POSTやDELETEなどの非冪等操作には使用しない
# 0-RTTの確認(OpenSSL 1.1.1以降)
$ openssl s_client -connect www.example.com:443 -tls1_3 \
    -sess_out /tmp/session.pem
$ openssl s_client -connect www.example.com:443 -tls1_3 \
    -sess_in /tmp/session.pem -early_data /tmp/request.txt

4.7 HelloRetryRequest

クライアントが提供したkey_shareがサーバーでサポートされていない場合、サーバーはHelloRetryRequestを送信して別のグループでの鍵共有を要求する。

クライアント                                サーバー
    │  ClientHello                             │
    │  + key_share: [x25519]                  │
    │─────────────────────────────────────────>│
    │                                          │
    │  HelloRetryRequest                       │
    │  + key_share: secp384r1を要求             │
    │<─────────────────────────────────────────│
    │                                          │
    │  ClientHello(再送)                      │
    │  + key_share: [secp384r1]               │
    │─────────────────────────────────────────>│
    │                                          │
    │  ServerHello(通常のハンドシェイク続行)    │
    │<─────────────────────────────────────────│

この場合、ハンドシェイクは2 RTTになる。

第5章: X.509証明書とPKI

5.1 X.509証明書の構造

Certificate {
    tbsCertificate {
        version:              v3 (2)
        serialNumber:         一意のシリアル番号
        signature:            署名アルゴリズム(例: sha256WithRSAEncryption)
        issuer:               発行者のDN(Distinguished Name)
        validity {
            notBefore:        開始日時
            notAfter:         終了日時
        }
        subject:              主体者のDN
        subjectPublicKeyInfo {
            algorithm:        公開鍵アルゴリズム
            subjectPublicKey: 公開鍵
        }
        extensions {
            basicConstraints:       CA: TRUE/FALSE, pathLenConstraint
            keyUsage:               digitalSignature, keyEncipherment, ...
            extKeyUsage:            serverAuth, clientAuth, ...
            subjectAltName:         DNS:www.example.com, DNS:example.com
            authorityKeyIdentifier: 発行者の鍵識別子
            subjectKeyIdentifier:   主体者の鍵識別子
            crlDistributionPoints:  CRL配布点
            authorityInfoAccess:    OCSPレスポンダURL, CA発行者URL
            certificatePolicies:    証明書ポリシー(DV/OV/EV)
        }
    }
    signatureAlgorithm:   署名アルゴリズム
    signatureValue:       発行者による署名
}

5.2 証明書の種類

種類検証内容信頼性コスト発行時間
DV(Domain Validation)ドメインの所有権のみ無料〜安価数分
OV(Organization Validation)ドメイン + 組織の実在性中程度数日
EV(Extended Validation)ドメイン + 組織の詳細審査高価数週間

5.3 証明書チェーンの検証

ルートCA証明書(自己署名)     ← ブラウザ/OSのトラストストアに格納
     │
     │  署名
     ▼
中間CA証明書                   ← サーバーが送信
     │
     │  署名
     ▼
サーバー証明書(エンドエンティティ) ← サーバーが送信

検証プロセス:

  1. サーバー証明書の署名を中間CA証明書の公開鍵で検証
  2. 中間CA証明書の署名をルートCA証明書の公開鍵で検証
  3. ルートCA証明書がトラストストアに存在するか確認
  4. 各証明書の有効期限を確認
  5. 各証明書が失効していないか確認(CRL/OCSP)
  6. サーバー証明書のSAN(Subject Alternative Name)がホスト名と一致するか確認
# 証明書チェーンの確認
$ openssl s_client -connect www.example.com:443 -showcerts

# 証明書の詳細表示
$ openssl s_client -connect www.example.com:443 2>/dev/null | \
    openssl x509 -noout -text

# 証明書の有効期限確認
$ openssl s_client -connect www.example.com:443 2>/dev/null | \
    openssl x509 -noout -dates
notBefore=Jan  1 00:00:00 2024 GMT
notAfter=Dec 31 23:59:59 2024 GMT

# SANの確認
$ openssl s_client -connect www.example.com:443 2>/dev/null | \
    openssl x509 -noout -ext subjectAltName

5.4 証明書の失効確認

CRL(Certificate Revocation List)

CAが発行する失効証明書のリスト。定期的にダウンロードして確認する。

# CRL配布点の確認
$ openssl x509 -in cert.pem -noout -text | grep -A 2 "CRL Distribution"

# CRLのダウンロードと確認
$ curl -o crl.der http://crl.example.com/ca.crl
$ openssl crl -in crl.der -inform DER -noout -text

OCSP(Online Certificate Status Protocol)

リアルタイムで個別の証明書の失効状態を確認するプロトコル。

# OCSPレスポンダURLの確認
$ openssl x509 -in cert.pem -noout -ocsp_uri

# OCSPリクエストの送信
$ openssl ocsp -issuer issuer.pem -cert server.pem \
    -url http://ocsp.example.com -resp_text

OCSP Stapling

サーバーが事前にOCSPレスポンスを取得し、TLSハンドシェイク中にクライアントに提供する。クライアントがOCSPレスポンダに直接問い合わせる必要がなくなる。

# OCSP Staplingの確認
$ openssl s_client -connect www.example.com:443 -status
# OCSP Response Data:
#     OCSP Response Status: successful (0x0)
#     Response Type: Basic OCSP Response
#     ...
#     Cert Status: good

Nginxでの設定:

server {
    listen 443 ssl;
    
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/ssl/chain.pem;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
}

5.5 Let's Encryptと自動証明書管理

Let's Encryptは、無料のDV証明書を自動発行するCA。ACME(Automatic Certificate Management Environment)プロトコルを使用する。

# certbotによる証明書の取得(Nginx)
$ sudo certbot --nginx -d www.example.com -d example.com

# 証明書の自動更新
$ sudo certbot renew --dry-run

# 証明書の自動更新(cron)
$ echo "0 3 * * * root certbot renew --quiet" | sudo tee /etc/cron.d/certbot-renew

# 証明書の確認
$ sudo certbot certificates

5.6 CT(Certificate Transparency)

CAが発行したすべての証明書を公開ログに記録し、不正な証明書発行を検知する仕組み。

# SCT(Signed Certificate Timestamp)の確認
$ openssl s_client -connect www.example.com:443 -ct_log_file ct_log_list.cnf

# CTログの検索
# https://crt.sh で証明書を検索可能

第6章: TLSの設定と実装

6.1 Nginxの設定

# /etc/nginx/conf.d/ssl.conf

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name www.example.com;

    # === 証明書 ===
    ssl_certificate /etc/ssl/certs/fullchain.pem;
    ssl_certificate_key /etc/ssl/private/privkey.pem;

    # === プロトコルバージョン ===
    ssl_protocols TLSv1.2 TLSv1.3;

    # === 暗号スイート ===
    # TLS 1.2の暗号スイート
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305';
    
    # サーバー側の暗号スイート優先
    ssl_prefer_server_ciphers on;

    # TLS 1.3の暗号スイート(OpenSSL 1.1.1以降)
    ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;

    # === セッション管理 ===
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;  # チケットの鍵管理が困難なため無効化推奨

    # === OCSP Stapling ===
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/ssl/certs/chain.pem;
    resolver 8.8.8.8 8.8.4.4 valid=300s;

    # === DH パラメータ ===
    ssl_dhparam /etc/ssl/dhparam.pem;  # 2048ビット以上

    # === ECDHカーブ ===
    ssl_ecdh_curve X25519:secp256r1:secp384r1;

    # === 0-RTT(TLS 1.3) ===
    ssl_early_data on;
    proxy_set_header Early-Data $ssl_early_data;

    # === セキュリティヘッダ ===
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header X-Content-Type-Options nosniff always;
    add_header X-Frame-Options DENY always;
}
# DHパラメータの生成
$ openssl dhparam -out /etc/ssl/dhparam.pem 2048

# 設定のテスト
$ sudo nginx -t

# Nginxの再読み込み
$ sudo systemctl reload nginx

6.2 Apacheの設定

# /etc/httpd/conf.d/ssl.conf

<VirtualHost *:443>
    ServerName www.example.com
    
    SSLEngine on
    SSLCertificateFile /etc/ssl/certs/fullchain.pem
    SSLCertificateKeyFile /etc/ssl/private/privkey.pem
    
    # プロトコルバージョン
    SSLProtocol -all +TLSv1.2 +TLSv1.3
    
    # 暗号スイート
    SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
    SSLCipherSuite TLSv1.3 TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256
    
    SSLHonorCipherOrder on
    
    # OCSP Stapling
    SSLUseStapling on
    SSLStaplingResponderTimeout 5
    SSLStaplingReturnResponderErrors off
    
    # HSTS
    Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
</VirtualHost>

SSLStaplingCache shmcb:/var/run/ocsp(128000)

6.3 OpenSSLコマンドリファレンス

# === 接続テスト ===

# TLS接続の確認
$ openssl s_client -connect www.example.com:443

# TLS 1.3での接続
$ openssl s_client -connect www.example.com:443 -tls1_3

# TLS 1.2での接続
$ openssl s_client -connect www.example.com:443 -tls1_2

# 特定の暗号スイートでの接続
$ openssl s_client -connect www.example.com:443 -cipher ECDHE-RSA-AES128-GCM-SHA256

# SNI指定
$ openssl s_client -connect 192.168.1.100:443 -servername www.example.com

# === 証明書操作 ===

# 自己署名証明書の作成(テスト用)
$ openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem \
    -days 365 -nodes -subj "/CN=localhost"

# CSR(証明書署名要求)の作成
$ openssl req -new -newkey rsa:2048 -keyout key.pem -out csr.pem -nodes \
    -subj "/C=JP/ST=Tokyo/L=Shibuya/O=Example Inc/CN=www.example.com"

# SAN付きCSRの作成
$ openssl req -new -newkey rsa:2048 -keyout key.pem -out csr.pem -nodes \
    -subj "/CN=www.example.com" \
    -addext "subjectAltName=DNS:www.example.com,DNS:example.com"

# ECDSA鍵と証明書の作成
$ openssl ecparam -genkey -name prime256v1 -out ec-key.pem
$ openssl req -new -x509 -key ec-key.pem -out ec-cert.pem -days 365 \
    -subj "/CN=www.example.com"

# 証明書の内容確認
$ openssl x509 -in cert.pem -noout -text

# 証明書のフィンガープリント
$ openssl x509 -in cert.pem -noout -fingerprint -sha256

# 秘密鍵と証明書の一致確認
$ openssl x509 -noout -modulus -in cert.pem | openssl md5
$ openssl rsa -noout -modulus -in key.pem | openssl md5
# 両方のMD5が一致すれば鍵ペアが正しい

# PEM → DER 形式変換
$ openssl x509 -in cert.pem -outform DER -out cert.der

# PKCS#12(PFX)形式への変換
$ openssl pkcs12 -export -out cert.pfx -inkey key.pem -in cert.pem -certfile chain.pem

# === 暗号化テスト ===

# 対応する暗号スイートの確認
$ openssl ciphers -v 'HIGH:!aNULL:!MD5'

# TLS 1.3の暗号スイート確認
$ openssl ciphers -v -tls1_3

# ベンチマーク
$ openssl speed aes-128-gcm aes-256-gcm chacha20-poly1305

6.4 curlでのTLS診断

# 詳細なTLS情報
$ curl -vI https://www.example.com 2>&1 | grep -E "SSL|TLS|subject|issuer|expire"

# TLSバージョンの指定
$ curl --tlsv1.3 https://www.example.com
$ curl --tlsv1.2 --tls-max 1.2 https://www.example.com

# 暗号スイートの指定
$ curl --ciphers ECDHE-RSA-AES128-GCM-SHA256 https://www.example.com

# 証明書検証の無効化(テスト用のみ)
$ curl -k https://self-signed.example.com

# クライアント証明書の使用
$ curl --cert client.pem --key client-key.pem https://mutual-auth.example.com

# 証明書チェーンの詳細
$ curl -w "
TLS Version: %{ssl_version}
Certificate Subject: %{ssl_verify_result}
" -sI https://www.example.com

6.5 testssl.shによるTLS診断

# testssl.shのインストール
$ git clone https://github.com/drwetter/testssl.sh.git
$ cd testssl.sh

# 基本的なスキャン
$ ./testssl.sh www.example.com

# 特定のチェック
$ ./testssl.sh --protocols www.example.com    # プロトコル
$ ./testssl.sh --ciphers www.example.com      # 暗号スイート
$ ./testssl.sh --vulnerabilities www.example.com  # 脆弱性
$ ./testssl.sh --headers www.example.com      # HTTPヘッダ

# JSON出力
$ ./testssl.sh --jsonfile result.json www.example.com

第7章: TLSセキュリティのベストプラクティスとTLS攻撃

7.1 プロトコルバージョン

推奨:
  ✅ TLS 1.3 — 最優先
  ✅ TLS 1.2 — 後方互換性のために許容

非推奨/禁止:
  ❌ TLS 1.1 — RFC 8996で禁止
  ❌ TLS 1.0 — RFC 8996で禁止
  ❌ SSL 3.0 — POODLE攻撃に脆弱
  ❌ SSL 2.0 — 多数の脆弱性

7.2 暗号スイートの選択

推奨暗号スイート(優先順):
  ✅ TLS_AES_128_GCM_SHA256          (TLS 1.3)
  ✅ TLS_AES_256_GCM_SHA384          (TLS 1.3)
  ✅ TLS_CHACHA20_POLY1305_SHA256    (TLS 1.3)
  ✅ ECDHE-ECDSA-AES128-GCM-SHA256  (TLS 1.2)
  ✅ ECDHE-RSA-AES128-GCM-SHA256    (TLS 1.2)
  ✅ ECDHE-ECDSA-AES256-GCM-SHA384  (TLS 1.2)
  ✅ ECDHE-RSA-AES256-GCM-SHA384    (TLS 1.2)
  ✅ ECDHE-ECDSA-CHACHA20-POLY1305  (TLS 1.2)
  ✅ ECDHE-RSA-CHACHA20-POLY1305    (TLS 1.2)

避けるべき暗号スイート:
  ❌ RC4系 — 統計的バイアスが存在
  ❌ CBC系 — パディングオラクル攻撃に脆弱
  ❌ 3DES — Sweet32攻撃に脆弱
  ❌ RSA鍵交換 — 前方秘匿性なし
  ❌ EXPORT系 — 意図的に弱い暗号
  ❌ NULL系 — 暗号化なし
  ❌ MD5/SHA-1ベース — 衝突攻撃が可能

7.3 HSTS(HTTP Strict Transport Security)

ブラウザにHTTPS接続のみを使用するよう指示するHTTPヘッダ。

Strict-Transport-Security: max-age=63072000; includeSubDomains; preload

  max-age: 有効期間(秒)— 63072000 = 2年
  includeSubDomains: サブドメインにも適用
  preload: HSTSプリロードリストへの登録(ブラウザに組み込み)
# HSTSプリロードリストへの登録
# https://hstspreload.org/ で登録申請

7.4 主要なTLS攻撃と対策

BEAST攻撃(Browser Exploit Against SSL/TLS)

  • 対象: TLS 1.0のCBCモード
  • 手法: CBCの初期化ベクトル(IV)が予測可能な点を悪用
  • 対策: TLS 1.1以上の使用、AES-GCMの使用

CRIME/BREACH攻撃

  • 対象: TLS圧縮 / HTTP圧縮
  • 手法: 圧縮率の差異からデータを推測
  • 対策: TLS圧縮の無効化(TLS 1.3では廃止)、HTTP圧縮の注意深い使用

POODLE攻撃(Padding Oracle On Downgraded Legacy Encryption)

  • 対象: SSL 3.0のCBCモード
  • 手法: CBCパディングの検証欠陥を悪用
  • 対策: SSL 3.0の無効化

Heartbleed(CVE-2014-0160)

  • 対象: OpenSSL 1.0.1〜1.0.1f
  • 手法: TLS Heartbeat拡張のバッファオーバーリードにより、サーバーメモリの内容(秘密鍵を含む可能性)を読み取り
  • 対策: OpenSSLのアップデート、秘密鍵の再生成、証明書の再発行

FREAK攻撃(Factoring RSA Export Keys)

  • 対象: EXPORT暗号スイートをサポートするサーバー
  • 手法: ダウングレード攻撃によりEXPORT暗号(512ビットRSA)を強制
  • 対策: EXPORT暗号スイートの無効化

Logjam攻撃

  • 対象: 512/768ビットDHパラメータ
  • 手法: 弱いDHパラメータを使用してDH鍵交換を攻撃
  • 対策: 2048ビット以上のDHパラメータ、ECDHEの使用

ROBOT攻撃(Return Of Bleichenbacher's Oracle Threat)

  • 対象: RSA鍵交換(PKCS#1 v1.5パディング)
  • 手法: パディングオラクル攻撃
  • 対策: RSA鍵交換の無効化、ECDHE鍵交換の使用

Downgrade攻撃

  • 手法: 中間者攻撃によりプロトコルバージョンや暗号スイートをダウングレード
  • 対策: TLS_FALLBACK_SCSV(RFC 7507)、TLS 1.3のdowngrade防止機構

7.5 Certificate Pinning

アプリケーションレベルで特定の証明書や公開鍵をピン留めし、CAの妥協による偽証明書を防ぐ。

# HTTP Public Key Pinning (HPKP) — 非推奨(Chrome 72で廃止)
# 代わりにCAAレコード、CTログの監視を推奨

# CAA(Certification Authority Authorization)DNSレコード
example.com.  IN  CAA  0  issue "letsencrypt.org"
example.com.  IN  CAA  0  issuewild "letsencrypt.org"
example.com.  IN  CAA  0  iodef "mailto:security@example.com"

第8章: TLSパフォーマンス最適化

8.1 TLSのパフォーマンスオーバーヘッド

レイテンシのオーバーヘッド:
  TLS 1.2: 2 RTT(フルハンドシェイク)/ 1 RTT(再開)
  TLS 1.3: 1 RTT(フルハンドシェイク)/ 0 RTT(再開)

CPU オーバーヘッド:
  RSA-2048署名: ~1ms(ハードウェアアクセラレーション有り)
  ECDSA-P256署名: ~0.1ms
  AES-GCM暗号化: AES-NIで ~1GB/s
  ChaCha20-Poly1305: ~500MB/s(ソフトウェア)

帯域幅のオーバーヘッド:
  TLSレコードヘッダ: 5バイト
  AES-GCMタグ: 16バイト
  パディング: 最大255バイト(TLS 1.3のレコードパディング)

8.2 セッション再開の最適化

# Nginx: セッションキャッシュの設定
ssl_session_cache shared:SSL:50m;  # 50MBの共有メモリ(約20万セッション)
ssl_session_timeout 1d;            # セッションの有効期間

# セッションチケットの鍵ローテーション
# 鍵ファイルの生成(48バイト = AES-256 + HMAC-SHA-256)
$ openssl rand 48 > /etc/ssl/ticket-key-current.pem
$ openssl rand 48 > /etc/ssl/ticket-key-previous.pem

# Nginx設定
ssl_session_ticket_key /etc/ssl/ticket-key-current.pem;
ssl_session_ticket_key /etc/ssl/ticket-key-previous.pem;
# 前回の鍵も保持することで、鍵ローテーション時のセッション断を防止

8.3 OCSP Staplingの最適化

# OCSPレスポンスのキャッシュサイズ確認
# Nginx: ssl_stapling_verify on;
# レスポンスは自動的にキャッシュされる

# OCSPレスポンスの有効期間確認
$ openssl ocsp -issuer issuer.pem -cert server.pem \
    -url http://ocsp.example.com -resp_text | grep "Next Update"

8.4 TLS 1.3 0-RTTの活用

# Nginx: 0-RTTの有効化
ssl_early_data on;

# バックエンドへの0-RTTデータの転送
proxy_set_header Early-Data $ssl_early_data;

# バックエンド側でリプレイ攻撃対策
# Early-Data: 1 ヘッダが存在する場合、冪等でないリクエストは拒否

8.5 ハードウェアアクセラレーション

# AES-NIの有無確認
$ grep -o aes /proc/cpuinfo | head -1
aes

# OpenSSLのエンジン確認
$ openssl engine
(rdrand) Intel RDRAND engine
(dynamic) Dynamic engine loading support

# AES-GCMのベンチマーク
$ openssl speed -evp aes-128-gcm
# AES-NI有り: ~4 GB/s
# AES-NI無し: ~500 MB/s

8.6 証明書の最適化

証明書サイズの比較:
  RSA-2048証明書: ~1KB
  RSA-4096証明書: ~2KB
  ECDSA-P256証明書: ~0.5KB

推奨:
  1. ECDSA証明書を使用(サイズが小さく、署名/検証が高速)
  2. 証明書チェーンを最小限に保つ(不要な中間証明書を省く)
  3. デュアルスタック(RSA + ECDSA)で互換性を確保
# デュアル証明書の設定(Nginx 1.11.0以降)
ssl_certificate /etc/ssl/ecdsa-fullchain.pem;
ssl_certificate_key /etc/ssl/ecdsa-privkey.pem;
ssl_certificate /etc/ssl/rsa-fullchain.pem;
ssl_certificate_key /etc/ssl/rsa-privkey.pem;

第9章: mTLS(相互TLS認証)

9.1 mTLSの概要

通常のTLSではサーバーのみが認証されるが、mTLS(mutual TLS)ではクライアントも証明書で認証される。マイクロサービス間通信、API認証、ゼロトラストネットワークで使用。

通常のTLS:
  クライアント ──→ サーバー証明書で認証 ──→ サーバー
  
mTLS:
  クライアント ←── サーバー証明書で認証 ──→ サーバー
  クライアント ──→ クライアント証明書で認証 → サーバー

9.2 mTLSの設定

# Nginx: mTLSの設定
server {
    listen 443 ssl;
    
    # サーバー証明書
    ssl_certificate /etc/ssl/server-cert.pem;
    ssl_certificate_key /etc/ssl/server-key.pem;
    
    # クライアント認証
    ssl_client_certificate /etc/ssl/client-ca.pem;  # クライアント証明書のCA
    ssl_verify_client on;        # 必須認証
    # ssl_verify_client optional; # オプション認証
    ssl_verify_depth 2;          # 証明書チェーンの深さ
    
    # クライアント証明書情報のバックエンドへの転送
    proxy_set_header X-SSL-Client-DN $ssl_client_s_dn;
    proxy_set_header X-SSL-Client-Verify $ssl_client_verify;
}

9.3 サービスメッシュでのmTLS

# Istio: mTLSの設定
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: istio-system
spec:
  mtls:
    mode: STRICT  # すべてのサービス間通信にmTLSを強制

第10章: TLSの最新動向と将来

10.1 Encrypted Client Hello(ECH)

TLS 1.3のClientHelloを暗号化し、SNIの盗聴を防止する拡張。

従来: ClientHello → SNI(平文)→ 接続先ホスト名が見える
ECH:  ClientHello → 外部ClientHello(ダミーSNI)+ 内部ClientHello(暗号化されたSNI)
      → 接続先ホスト名が保護される

10.2 Post-Quantum TLS

量子コンピュータによる暗号解読に備えた暗号アルゴリズムの標準化が進行中。

ポスト量子暗号アルゴリズム(NIST標準化):
  - ML-KEM(Kyber): 鍵カプセル化メカニズム(鍵交換用)
  - ML-DSA(Dilithium): デジタル署名
  - SLH-DSA(SPHINCS+): ハッシュベースの署名

ハイブリッドアプローチ:
  TLSで従来の鍵交換(ECDHE)とポスト量子鍵交換を組み合わせる
  例: X25519 + ML-KEM-768
# OpenSSLでのポスト量子サポート確認(OQS Provider使用時)
$ openssl list -kem-algorithms | grep -i kyber

10.3 TLS over QUIC

QUIC(HTTP/3のトランスポート)は、TLS 1.3をUDP上に統合している。TCP+TLSの代替として急速に普及中。

従来: TCP 3ウェイハンドシェイク(1 RTT) + TLS 1.3ハンドシェイク(1 RTT) = 2 RTT
QUIC: QUIC + TLS 1.3 統合ハンドシェイク = 1 RTT(0-RTTも可能)

まとめ

TLSはインターネットセキュリティの根幹であり、その正しい理解と設定は全てのエンジニアに求められる。本記事の要点:

  1. 暗号技術の基礎: 対称暗号(AES-GCM)、公開鍵暗号(ECDSA)、鍵交換(ECDHE)、AEAD
  2. TLS 1.2: 2 RTTのハンドシェイク、セッション再開
  3. TLS 1.3: 1 RTTハンドシェイク、0-RTT、前方秘匿性必須、脆弱アルゴリズムの廃止
  4. PKI/証明書: X.509構造、チェーン検証、OCSP Stapling、Let's Encrypt
  5. 設定実践: Nginx/Apache設定、OpenSSLコマンド
  6. セキュリティ: BEAST/POODLE/Heartbleed等の攻撃と対策、HSTS
  7. パフォーマンス: セッション再開、0-RTT、ハードウェアアクセラレーション、ECDSA証明書
  8. mTLS: 相互認証、サービスメッシュ
  9. 将来: ECH、ポスト量子暗号、QUIC

参考文献

  • RFC 5246 - The Transport Layer Security (TLS) Protocol Version 1.2 (2008)
  • RFC 8446 - The Transport Layer Security (TLS) Protocol Version 1.3 (2018)
  • RFC 6066 - TLS Extensions: Extension Definitions (2011)
  • RFC 6961 - TLS Multiple Certificate Status Request Extension (2013)
  • RFC 7301 - TLS Application-Layer Protocol Negotiation Extension (2014)
  • RFC 7507 - TLS Fallback Signaling Cipher Suite Value (2015)
  • RFC 7525 - Recommendations for Secure Use of TLS and DTLS (2015)
  • RFC 8996 - Deprecating TLS 1.0 and TLS 1.1 (2021)
  • RFC 9325 - Recommendations for Secure Use of TLS and DTLS (2022)
  • "Bulletproof SSL and TLS" - Ivan Ristić
  • Mozilla SSL Configuration Generator: https://ssl-config.mozilla.org/
  • SSL Labs Server Test: https://www.ssllabs.com/ssltest/