TLS接続の往復回数や暗号処理は、バージョン、鍵交換方式、再開の有無、ネットワーク条件で異なります。すべての完全ハンドシェイクが必ず1〜2 RTTを要し、TTFBを悪化させるとは一般化できません。セッション再開は以前の接続で確立したPSKを後続のハンドシェイクに利用できますが、任意の0-RTT早期データには別途リプレイリスクの評価が必要です。

光る弧でつながる2つの石の球体と、浮かぶ金色の球体を描いた抽象イラスト

1. TLS 1.3におけるPSK統合とNewSessionTicketの暗号構造

TLS 1.3ではセッション再開に事前共有鍵(PSK)を使用できます。ハンドシェイク後、サーバーはNewSessionTicketを送信でき、クライアントとサーバーは後続接続で再開情報として利用します。RFC 8446はClientHelloでPSK identityとbinderを提示し、サーバーが受理を判断する手順を定めています。チケットの内部形式や鍵の保護方法は実装に依存するため、すべてのサーバーが同じ項目を専用鍵で暗号化すると断定できません。

2. 0-RTT早期データとリプレイの危険

TLS 1.3では以前のセッションから得たPSKでハンドシェイク完了前に早期データを送れますが、セッション再開そのものに0-RTTは必須ではありません。再開したPSK接続でも完了後にアプリケーションデータを送れます。RFC 8446によると0-RTTはリプレイされ得て、前方秘匿性を提供しません。状態変更や重複実行で問題が起きる処理は早期データに含めず、TLSが重複処理を防ぐとも想定しないでください。またPSK-onlyと(EC)DHEを組み合わせたPSK交換では前方秘匿性が異なります。再開が公開鍵処理や認証確認をすべて省くとは限りません。

CloudflareのTLS 1.3解説は、セッションチケットを使うサーバーが早期データを以前処理したか常に判断できるとは限らない例を示し、状態を変更しない処理に限る考え方を説明しています。RFC 8446も、アプリケーションプロトコルでリプレイ安全性を評価し、適切なプロファイルなしに0-RTTを使わないよう求めています。GETなら常に安全とは限りません。実際のルートで副作用、重複実行、複数サーバー間の再送対策を確認します。危険を評価できない場合、その処理では早期データを無効にし、ハンドシェイク後に実行します。

RFC 8446では早期データを受け入れる際、サーバーがPSK暗号スイートを選び、提示順の先頭のPSKを採用し、TLS版・暗号スイート・ALPNなど関連パラメーターを確認する必要があります。これらの確認に成功しても、アプリケーション側のリプレイ対策は別途必要です。状態モデルが許す場合は冪等性キーや重複排除を使い、再実行を許容できない処理は通常のハンドシェイク完了後に行います。チケットの受理、早期データの受理、アプリケーション認可は別の判断です。

3. 早期データを操作ごとに確認

運用レビューではセッション再開と0-RTTの有効化を別項目として記録し、同じ条件で完全ハンドシェイクと再開時の遅延・計算量を比較します。チケット発行とPSK選択の動作を観測しますが、TLS仕様だけから実装ごとのチケット鍵管理を推測しないでください。性能測定だけではリプレイ安全性を確認できません。

参考資料および公式リンク