TCP接続とTLSハンドシェイク
IPアドレスが判明すると、ブラウザはWebサーバーとの間に通信パイプを開通させます。インターネットは信頼性のないネットワークの集合体であるため、ここで「信頼性の確立(TCP)」と「安全性の確立(TLS)」という二重のハンドシェイクが行われます。
3.1 TCP 3ウェイ・ハンドシェイク (The 3-Way Handshake)
HTTP(HTTP/3を除く)は、 TCP (Transmission Control Protocol) というトランスポート層プロトコルに依存しています。TCPはパケットの順序保証、欠損時の再送、輻輳制御などを提供します。接続を確立するために、以下の3ステップの儀式が必要です。
- SYN (Synchronize):
クライアント(ブラウザ)はサーバーに対し、「接続したい」という意思表示としてSYNフラグを立てたパケットを送信します。この時、初期シーケンス番号(ISN) というランダムな数値を生成して送ります。これは後の通信でパケットの順序を管理するための基準点となります。 - SYN-ACK (Synchronize-Acknowledge):
サーバーはオープンなポート(通常443)で待ち受けており、クライアントからのSYNを受け取ります。接続を許可する場合、サーバー側のISNと、クライアントのISNに1足した確認応答番号(ACK番号)を含めたパケット(SYN+ACK)を返送します。 - ACK (Acknowledge):
クライアントはサーバーからのSYN-ACKを受け取り、サーバーのISNに1足した値をACK番号として送り返します。このパケットがサーバーに届いた時点で、論理的な接続が確立(ESTABLISHED状態)されます。
この往復により、1回分の往復遅延時間 (1-RTT: Round Trip Time) が必ず発生します。地球の裏側のサーバーにアクセスする場合、これだけで数百ミリ秒を消費する可能性があります。
3.2 TLSハンドシェイク (Transport Layer Security)
TCP接続が確立されると、その上で暗号化通信のための TLSハンドシェイク が始まります。現代のWebではHTTPSが事実上の標準であり、セキュリティだけでなく、HTTP/2などの新機能を利用するための必須要件ともなっています。
3.2.1 TLS 1.2 vs TLS 1.3:速度と安全性の革命
TLSのバージョンによって、ハンドシェイクの手順と所要時間は大きく異なります。特に2018年に標準化されたTLS 1.3は、劇的なパフォーマンス向上をもたらしました。
以下の表は、TLS 1.2と1.3の主要な違いをまとめたものです。
| 特徴 | TLS 1.2 | TLS 1.3 |
|---|---|---|
| ハンドシェイク回数 | 2-RTT (2往復) | 1-RTT (1往復) |
| 鍵交換アルゴリズム | RSA (静的), Diffie-Hellmanなど多数 | Ephemeral Diffie-Hellman (ECDHE) のみ |
| 暗号スイート | 多数の組み合わせ (脆弱なもの含む) | 安全なAEAD暗号のみ (5種類) |
| Server Hello後の暗号化 | サーバー証明書などは平文 | サーバー証明書を含めほぼ全て暗号化 |
| 0-RTT 再開 | 非対応 | 対応 (再接続時にデータ送信可能) |
3.2.2 TLS 1.3の詳細フロー (1-RTT)
TLS 1.3では、クライアントが「推測」を行うことで往復回数を減らしています。
- Client Hello + Key Share:
クライアントは「TLS 1.3を使いたい」という意思表示と共に、サポートする暗号リストを送ります。さらに、サーバーがこれを選ぶだろうと予測して、鍵交換に必要なパラメータ(Key Share:楕円曲線暗号の公開鍵の一部など)を最初から送りつけます。 - Server Hello + Key Share + Server Finished:
サーバーはクライアントの予測が正しければ、自身のKey Shareとサーバー証明書、署名を生成し、これらをまとめて返します。驚くべきことに、TLS 1.3ではこの段階からすでに一部のデータが暗号化されています。 - Client Finished:
クライアントはサーバー証明書を検証し、共通鍵(セッションキー)を生成します。これ以降の通信はすべてこの鍵で暗号化されます。
さらに、0-RTT(ゼロラウンドトリップ) という機能を使えば、過去に接続したサーバーに対しては、最初のハンドシェイクパケットの中に暗号化されたHTTPリクエスト(GET / index.htmlなど)を潜ませて送ることが可能です。これにより、TLSのオーバーヘッドは見かけ上ゼロになります。