合同会社小村ソフト
第 5 章

TLS 1.3 ハンドシェイク — 1 往復で通信路を作る

ClientHello から Finished まで、鍵合意・証明書・署名・改ざん検知が 1 往復に組み上がる流れを追い、SNI と 1-RTT の意味をつかむ。

部品はそろった — あとは組み上げるだけ

ここまでの章で、必要な部品はすべて手に入りました。鍵合意(第 3 章)で盗聴されている経路の上に共有秘密を作り、証明書と署名(第 2・4 章)で相手が本物であることを確かめ、共通鍵暗号と改ざん検知(第 2 章)で本文を守る。TLS 1.3 のハンドシェイクは、これらをたった 1 往復に組み上げる手順です。

この章では「次に何が起きるか」を丸暗記するのではなく、各メッセージを見るたびにどの章の道具が、どの問いに答えるために登場したかを確認しながら進みます。

ClientHello から Finished までの TLS 1.3 ハンドシェイクの往復と、各メッセージの役割を示すシーケンス図

TLS 1.3 ハンドシェイクの全体像。ServerHello の時点で鍵合意が完了し、以降のメッセージ(グレーの領域)はすでに暗号化されています。

行き: ClientHello — 名乗りと公開値を一度に

クライアントが最初に送る ClientHello には、次が載っています。

  • 対応できる TLS バージョンと暗号方式の候補 — 「私はこれらが話せます」
  • key_share = DH(ECDHE)の公開値 — 第 3 章の「A」を初手で同梱
  • SNI(Server Name Indication) — 接続したいホスト名。1 つの IP で複数ドメインを運用するサーバが、どの証明書を出すか選ぶために必要

TLS 1.2 までは「方式を合意する往復」と「鍵を交換する往復」が別で、合計 2 往復かかっていました。TLS 1.3 は公開値を初手に同梱することで、これを 1 往復に圧縮しています。なお ClientHello は鍵共有のメッセージなので暗号化できず、SNI のホスト名は経路上から見えます — 第 1 章の「HTTPS でもドメイン名は見える」の正体です。

帰り: ServerHello から Finished まで — 一気に畳みかける

サーバは選んだ方式と自分の公開値(key_share)を ServerHello で返します。この瞬間、両者は共有秘密を計算できます。TLS 1.3 はすぐに鍵を導出し、以降のメッセージをすべて暗号化した上で、同じ便にまとめて送ります。

Certificate — 「私はこのドメインの持ち主です」
証明書チェーンを提示。クライアントは第 4 章の 3 チェック(署名チェーン・有効期間・名前照合)で検証する
CertificateVerify — 「その証拠に、秘密鍵を持っています」
ここまでのハンドシェイク全体への署名。その場でしか作れない内容に署名するので、証明書のコピーやリプレイでは偽造できない
Finished — 「ここまでの会話、食い違いはありませんね」
ハンドシェイク全体の記録から鍵付きで計算した検証値。途中で候補を弱い方式にすり替えるような改ざんがあれば、ここで発覚する

クライアントは検証を終えると自分の Finished を返し、同じ便でアプリケーションデータ(HTTP リクエスト)を送り始められます。ClientHello からここまで 1 往復 — これが「1-RTT ハンドシェイク」です。

小問 5-1 — 1 往復の中身を追う

ハンドシェイクの各メッセージが「どの章の道具か」を意識しながら答えてください。

Q1. TLS 1.3 の ClientHello には、対応バージョンや暗号方式の候補と一緒に、DH の公開値(key_share)が最初から同梱されています。この設計の狙いはどれですか。

Q2. クライアントとサーバの間の往復時間(RTT)が 100 ミリ秒とします。TCP 接続の確立後、ClientHello を送ってからクライアントが暗号化されたアプリケーションデータ(HTTP リクエストなど)を送り始められるまで、最短で何ミリ秒かかりますか。

ミリ秒

Q3. サーバが送る CertificateVerify の役割はどれですか。

ハンドシェイクの後 — 共有秘密がそのまま鍵になるわけではない

細部ですが、実務の会話で効く点を 2 つ補っておきます。

鍵は用途別に導出される。第 3 章の共有秘密をそのまま暗号鍵に使うのではなく、鍵導出関数(HKDF)に通して「クライアント→サーバ用」「サーバ→クライアント用」など方向別・用途別の鍵を複数作ります。1 つの秘密から役割の違う鍵を派生させる — どれかが解析されても他に波及しにくくする設計です。

暗号化と改ざん検知は一体で行われる。本文の保護には認証付き暗号(AEAD。AES-GCM など)が使われ、暗号化と改ざん検知(第 2 章の MAC の役割)を 1 つの演算でまとめて行います。「暗号化はされているが改ざん検知を忘れた」という組み合わせ事故が起きない構造です。

また、一度接続したサーバとは、発行されたチケット(PSK)を使って次回のハンドシェイクを軽くするセッション再開もあります。さらに再開時には最初の便にデータを載せる 0-RTT という高速化もありますが、この便だけはリプレイ攻撃(攻撃者が同じデータをもう一度送りつける)を検知できないため、GET のような何度実行されても害のない操作に限る、という注意付きです。

小問 5-2 — 設計の意図を読む

「なぜそうなっているか」を答える問題です。第 1 章の伏線もここで回収します。

Q4. TLS 1.3 では、サーバが送る証明書(Certificate)はどんな状態で経路を流れますか。

Q5. ハンドシェイクの最後に両者が交換する Finished メッセージの役割はどれですか。

Q6. 第 1 章で「HTTPS でも接続先のドメイン名は経路上から見える」と学びました。その理由として正しいものはどれですか。

この章で持ち帰ること

  • TLS 1.3 はClientHello に公開値を同梱して 1 往復でハンドシェイクを終える。証明書以降はすでに暗号化されている
  • CertificateVerify = その場の内容への署名による秘密鍵の所持証明Finished = ハンドシェイク全体の改ざん検知
  • 鍵は HKDF で用途別に導出し、本文はAEAD で暗号化と改ざん検知を一体で行う
  • SNI は鍵共有前に流れるので見える。0-RTT は速いがリプレイに注意

仕組みの学習はここまでで一巡です。次章では openssl とブラウザを使って、この章まで頭で追ってきたものを実物で観察します。