5. パケット保護 (Packet Protection)
TCP上のTLSと同様に、QUICはTLSハンドシェイクから派生した鍵を使用してパケットを保護し、TLSによってネゴシエートされたAEADアルゴリズム[AEAD]を使用します。
QUICパケットは、そのタイプに応じて異なる保護を持ちます:
-
バージョンネゴシエーション(Version Negotiation)パケットには暗号化保護がありません。
-
リトライ(Retry)パケットはAEAD_AES_128_GCMを使用して、偶発的な変更に対する保護を提供し、有効なリトライを生成できるエンティティを制限します(セクション5.8を参照)。
-
初期(Initial)パケットはAEAD_AES_128_GCMを使用し、クライアントが送信した最初の初期パケットの宛先接続ID(Destination Connection ID)フィールドから派生した鍵を使用します(セクション5.2を参照)。
-
その他すべてのパケットは、TLSによってネゴシエートされた鍵とアルゴリズムを使用した強力な暗号化機密性と完全性保護を持ちます。
このセクションでは、ハンドシェイク、0-RTT、および1-RTTパケットにパケット保護を適用する方法について説明します。同じパケット保護プロセスが初期パケットに適用されます。ただし、初期パケットに使用される鍵を決定することは簡単であるため、これらのパケットは機密性または完全性保護を持つとは見なされません。リトライパケットは固定鍵を使用するため、機密性と完全性保護も欠いています。
5.1. パケット保護鍵 (Packet Protection Keys)
QUICは、TLSがレコード保護鍵を派生するのと同じ方法でパケット保護鍵を派生します。
各暗号化レベルには、各方向に送信されるパケットを保護するための個別の秘密値があります。これらのトラフィックシークレット(traffic secrets)はTLSによって派生され([TLS13]のセクション7.1を参照)、初期暗号化レベルを除くすべての暗号化レベルでQUICによって使用されます。初期暗号化レベルの秘密は、セクション5.2で説明されているように、クライアントの初期宛先接続IDに基づいて計算されます。
パケット保護に使用される鍵は、TLSが提供するKDFを使用してTLS秘密から計算されます。TLS 1.3では、[TLS13]のセクション7.1で説明されているHKDF-Expand-Label関数が使用され、ネゴシエートされた暗号スイートのハッシュ関数を使用します。QUICにおけるHKDF-Expand-Labelのすべての使用は、長さゼロのコンテキスト(Context)を使用します。
文字列として記述されたラベル(Labels)は、引用符や末尾のNULバイトなしでASCII [ASCII]を使用してバイトにエンコードされることに注意してください。
現在の暗号化レベルの秘密とラベル"quic key"がKDFへの入力として使用され、AEAD鍵を生成します。ラベル"quic iv"は初期化ベクトル(IV)を派生するために使用されます(セクション5.3を参照)。ヘッダー保護鍵はラベル"quic hp"を使用します(セクション5.4を参照)。これらのラベルの使用により、QUICとTLSの間で鍵の分離が提供されます(セクション9.6を参照)。
"quic key"と"quic hp"は両方とも鍵を生成するために使用されるため、これらのラベルでHKDF-Expand-Labelに提供される長さは、AEADまたはヘッダー保護アルゴリズムの鍵サイズによって決定されます。"quic iv"に提供される長さは、最小AEADノンス長、またはそれより大きい場合は8バイトです([AEAD]を参照)。
初期秘密に使用されるKDFは常にTLS 1.3 HKDF-Expand-Label関数です(セクション5.2を参照)。
5.2. 初期シークレット (Initial Secrets)
初期パケットはパケット保護プロセスを適用しますが、クライアントが送信した最初の初期パケットの宛先接続IDフィールドから派生した秘密を使用します。
この秘密はHKDF-Extractを使用して決定されます([HKDF]のセクション2.2を参照)。ソルト(salt)は0x38762cf7f55934b34d179ae6a4c80cadccbb7f0aで、入力鍵材料(IKM)は宛先接続IDフィールドです。これにより、送信と受信の2つの別々の秘密を派生するために使用される中間疑似ランダム鍵(PRK)が生成されます。
クライアントが初期パケットを構築するために使用する秘密は、PRKとラベル"client in"をTLSのHKDF-Expand-Label関数[TLS13]への入力として使用し、32バイトの秘密を生成します。サーバーによって構築されたパケットは、ラベル"server in"を使用して同じプロセスを使用します。初期秘密と鍵の派生のためのHKDFのハッシュ関数はSHA-256 [SHA]です。
このプロセスの疑似コードは次のとおりです:
initial_salt = 0x38762cf7f55934b34d179ae6a4c80cadccbb7f0a
initial_secret = HKDF-Extract(initial_salt,
client_dst_connection_id)
client_initial_secret = HKDF-Expand-Label(initial_secret,
"client in", "",
Hash.length)
server_initial_secret = HKDF-Expand-Label(initial_secret,
"server in", "",
Hash.length)
HKDF-Expand-Labelで使用される接続IDは、クライアントが送信した初期パケットの宛先接続IDです。これは、クライアントがリトライパケットを受信した後に初期パケットを作成する場合を除き、ランダムに選択された値になります。その場合、宛先接続IDはサーバーによって選択されます。
将来のQUICバージョンは新しいソルト値を生成すべきであり(SHOULD)、それによって各QUICバージョンの鍵が異なることを保証します。これにより、1つのQUICバージョンのみを認識するミドルボックスが将来のバージョンのパケット内容を見たり変更したりすることを防ぎます。
初期パケットは、提供されるTLSバージョンにTLS 1.3が含まれていない場合でも、TLS 1.3で定義されているHKDF-Expand-Label関数を使用しなければなりません(MUST)。
サーバーがリトライパケットを送信し、サーバーが選択した接続ID値を使用すると、後続の初期パケットを構築するために使用される秘密が変更されます。サーバーの初期パケットに応答してクライアントが使用する宛先接続IDは秘密を変更しません。
| 注意:宛先接続IDフィールドは最大20バイトの長さ、またはサーバーが長さゼロのソース接続IDフィールドを | 持つリトライパケットを送信した場合は長さゼロである可能性があります。リトライ後、初期鍵はサーバーが | クライアントのパケットを受信したことを保証しないため、クライアントはリトライパケットを含む交換に依存 | してサーバーのアドレスを検証する必要があります([QUIC-TRANSPORT]のセクション8.1を参照)。
付録Aには初期パケットの例が含まれています。
5.3. AEADの使用 (AEAD Usage)
QUICパケット保護に使用される関連データ付き認証暗号化(AEAD)関数([AEAD]を参照)は、TLS接続で使用するためにネゴシエートされたAEADです。たとえば、TLSが暗号スイートTLS_AES_128_GCM_SHA256を使用する場合、AEAD_AES_128_GCM関数が使用されます。
QUICは、TLS_AES_128_CCM_8_SHA256を除き、[TLS13]で定義されている任意の暗号スイートを使用できます。暗号スイートのヘッダー保護スキームが定義されていない限り、暗号スイートをネゴシエートしてはなりません(MUST NOT)。このドキュメントは、TLS_AES_128_CCM_8_SHA256を除き、[TLS13]で定義されているすべての暗号スイートのヘッダー保護スキームを定義します。これらの暗号スイートには16バイトの認証タグがあり、入力より16バイト大きい出力を生成します。
エンドポイントは、サポートしていない暗号スイートを提供するClientHelloを拒否してはなりません(MUST NOT)。そうしないと、新しい暗号スイートを展開できなくなります。これはTLS_AES_128_CCM_8_SHA256にも適用されます。
パケットを構築する際、ヘッダー保護を適用する前にAEAD関数が適用されます(セクション5.4を参照)。保護されていないパケットヘッダーは関連データ(A)の一部です。パケットを処理する際、エンドポイントは最初にヘッダー保護を削除します。
パケット鍵とIVはセクション5.1で説明されているように計算されます。ノンス(N)は、IVをパケット番号と組み合わせることによって形成されます。ネットワークバイトオーダーで再構築された62ビットのQUICパケット番号は、IVのサイズまでゼロで左詰めされます。埋め込まれたパケット番号とIVの排他的論理和(XOR)がAEADノンスを形成します。
AEADの関連データAは、QUICパケットヘッダーの内容で、短いヘッダーまたは長いヘッダーの最初のバイトから始まり、保護されていないパケット番号まで含みます。
AEADの平文Pは、[QUIC-TRANSPORT]で説明されているQUICパケットペイロードです。
AEADの暗号文CはPの代わりに送信されます。
一部のAEAD関数には、同じ鍵とIVで暗号化できるパケット数に制限があります(セクション6.6を参照)。これはパケット番号制限より低い場合があります。エンドポイントは、使用中のAEAD構成によって課される制限を超える前に鍵更新(セクション6)を開始しなければなりません(MUST)。
5.4. ヘッダー保護 (Header Protection)
QUICパケットヘッダーの一部、特にパケット番号フィールドは、パケット保護鍵とIVとは別に派生した鍵を使用して保護されます。ラベル"quic hp"を使用して派生した鍵は、パス上の要素に公開されないフィールドに機密性保護を提供するために使用されます。
この保護は、最初のバイトの最下位ビットとパケット番号フィールドに適用されます。長いヘッダーパケットの場合、最初のバイトの4つの最下位ビットが保護されます。短いヘッダーパケットの場合、最初のバイトの5つの最下位ビットが保護されます。両方のヘッダー形式について、これは予約(Reserved)ビットとパケット番号長(Packet Number Length)フィールドをカバーします。短いヘッダーパケットの鍵フェーズ(Key Phase)ビットも保護されます。
同じヘッダー保護鍵が接続全体に使用され、その値は鍵更新後も変更されません(セクション6を参照)。これにより、ヘッダー保護を使用して鍵フェーズを保護できます。
このプロセスは、保護されたペイロードを含まないか、このプロセスによって保護されるフィールドを含まないリトライまたはバージョンネゴシエーションパケットには適用されません。
注意:ドキュメントの長さを制限し完全性を確保するため、残りのセクション(5.4.1-5.8)の完全な技術詳細については、元のRFC 9001テキストを参照することをお勧めします。これには以下が含まれます:
- 5.4.1. ヘッダー保護の適用
- 5.4.2. ヘッダー保護サンプル
- 5.4.3. AESベースのヘッダー保護
- 5.4.4. ChaCha20ベースのヘッダー保護
- 5.5. 保護されたパケットの受信
- 5.6. 0-RTT鍵の使用
- 5.7. 順不同の保護されたパケットの受信
- 5.8. リトライパケットの完全性
完全な技術ドキュメントについては、次を参照してください:
https://www.rfc-editor.org/rfc/rfc9001.html#section-5