はじめに
RFC9147(日本語) : DTLS1.3が発行されたので、1.3で何が変わったのか少しまとめてみました。なお、RFCの "12. Changes since DTLS 1.2" にも変更点のまとめがあります。また、DTLSの一般的な説明については「組込み向けDTLSを試してみる」の記事も参照してください。
一口で言うと、DTLS1.3はTLS1.3の成果を取り込んだことで、セキュリティ上の改善とともにデータグラム向けのよりスループットの高いセキュリティプロトコルになったと言えそうです。
プロトコル仕様の位置付けの観点からは、DTLS1.2はDTLS1.0(*)からの差分として定義されたのに対して、DTLS1.3は(DTLS1.2ではなく)TLS1.3からの差分として定義されている点がこれまでと大きくことなっています。
*: DTLS1.1は存在しません
1. ハンドシェーク
ハンドシェークプロトコルは大きく変わりました。TLS1.2から1.3への更新と同じようにTLS1.3流のフルハンドシェーク、ClientRetryRequest、PSK(DHあり、なし)、Early Dataがほぼそのまま導入されています。ただし、もちろんこれまでのDTLSと同様にTCP上ではなくそれらをデータグラム上で実現します。
それに伴って、リプレイ攻撃対策のCookieもHello Verify Requestではなく、TLS1.3流のHello Retry Requestによって実現するようになりました。
これらによって、クライアント・サーバ間のメッセージの往復回数が削減されスループットの向上が期待できます。これらはUDPのようなデータグラムの上で実現するのでTCPの3Wayハンドシェークのような接続プロトコルも不要です。
ACKメッセージが追加され、パケットロスはタイムアウトを待たずに早期に検知できるようになりました。
セキュリティ的観点からは、これもTLS1.3と同様に、鍵交換が(EC)DHEだけに絞られ、古く弱い暗号アルゴリズムは廃止、AEADのみに整理されました。
ServerHello以降のハンドシェークは暗号化され、秘匿性の向上も期待できます。
2. DTLSレコード
DTLSレコード層には、DTLS1.2と互換のフォーマットに加えて、状況に応じたフォーマットが柔軟に選択できるようなマルチプレクシングが導入されました。
今までドラフトだった接続ID(Connection ID)が正式に追加されました。これにより、移動体の通信などのルーティングの動的な変更に対応できるようになりました。
3. アプリケーション・レコード
一方、アプリケーションメッセージの扱いについては、特段の変更はありません。これまで通りデータグラム層の特性(順序性の不保証、パケットロスなど)はそのままアプリケーション層に引き継がれ、UDPなどデータグラム上のアプリケーションはそのままの挙動を維持することになります。
4. DTLS1.2/1.3 比較表
レイヤー/ フェーズ |
項目 | DTLS1.2 | DTLS1.3 |
---|---|---|---|
ハンド シェーク |
暗号 スイート |
TLS1.2相当 | TLS1.3相当 弱い暗号アルゴリズムの削除 (EC)DHEのみに AEADのみに |
シーケンス | TLS1.2相当 | TLS1.3相当のハンドシェーク - フルハンドシェーク - ClientRetryRequest - PSK(DHあり、なし) - Early Data |
|
Cookie | Cookie = HMAC(Secret, Client-IP, Client-Parameters) Hello Verify Request必ず必要 |
HelloRetryRequestによるCookie要求 | |
タイム アウト |
デフォルト: 初期1000mSec。タイムアウトごとに倍に 最大60Sec アプリケーションにより適宜変更可 |
ACKメッセージの追加(次項目参照) | |
パケット 消失 |
タイムアウトによる検出 期待する応答メッセージが一定時間までに受信 されなかった場合、メッセージを再度送信 |
ACKメッセージの追加 タイムアウト前に消失を検知 |
|
パケット 順序 |
message_seqで管理 再送ではインクリメントされない Renegotiationでリセット |
message_seqで管理 再送ではインクリメントされない ポストハンドシェーク中も リセットされない |
|
大きい パケット |
fragment_offset fragment_lengthで管理 |
||
ポスト ハンド シェーク |
TLS1.3相当 - New Session Ticket - Key Update - Client Authentication DTLS1.3固有 - New Connection ID - Req Connection ID |
||
アプリ ケーション データ |
パケット 消失 |
Don't Care | 変更なし |
パケット 順序 |
Don't Care | 変更なし | |
パケット サイズ |
Don't Care | 変更なし | |
フロー制御 | なし | 変更なし | |
DTLS レコード |
レコード ヘッダー |
TLS1.2のレコードヘッダに epoch sequence_numberを追加 |
可変長、複数フォーマット |
フラグメント | ハンドシェーク中 フラグメント管理 一つのDTLSは一つのデータグラムに |
変更なし | |
接続ID | ドラフト | 複数CID ポストハンドシェークで変更可 |
|
レコード 順序 |
sequence_numberとepochで管理 sequence_numberは新epochでリセット |
基本的に踏襲 強化:[sender]_sn_keyにて暗号化 追加 rekeyでインクリメント |
|
PMTU | 基本的には感知せず。ただし、 - DTLSレコードのサイズ - ICMP - DTLSハンドシェークメッセージのサイズ |
変更なし | |
不正 レコード |
無視 | 変更なし | |
AEAD 制限長 |
定義なし | 例: AEAD_AES_128_CCM: 2^23 |