この資料は、TLS1.3 (RFC8446)「2. プロトコル概要 (Protocol overview)」の翻訳です。
原文: https://www.rfc-editor.org/rfc/rfc8446.txt
参考リンク:wolfSSL: TLS 1.3 製品ページ
wolfSSLホーム:www.wolfssl.jp (English:www.wolfssl.com)
2. プロトコル概要
セッション状態の暗号化パラメータはTLSハンドシェイク・プロトコルで生成される。このTLSのサブプロトコルはクライアントとサーバーが互いに最初に通信する際に使用される。ハンドシェイクプロトコルは、プロトコル・バージョン、暗号化アルゴリズムの選択、オプションとしてお互いの認証、共有の秘密の鍵の元について確立する。ハンドシェイクが完了したら、通信の双方はアプリケーション層通信を守るために確立した鍵を使用する。
ハンドシェイクの失敗またはその他のプロトコルエラーは接続終了のトリガーとなると同時にアラートメッセージが続く場合がある。
TLSは3つの基本的鍵交換モードをサポートする:
- (EC)DHE (有限状態あるいは楕円曲線によるディフィー・ヘルマン )
- 事前共有鍵(PSK)のみ
- (EC)DHEをともなうPSK
図1は基本的なフルTLSハンドシェイクを示す。
図1フルTLSハンドシェイクのメッセージ・フロー
上図に示すように、ハンドシェイクは3つのフェーズと考えられる。
- 鍵交換:共有鍵の元を確立し暗号化パラメータを選択する。以後のすべては暗号化される。
- サーバ・パラメータ:その他のハンドシェイク・パラメータを確立する。(クライアント認証されるか、アプリケーション層プロトコルサポート、その他)
- 認証:サーバ(オプションとしてクライアント)認証、 鍵の確認とハンドシェイクの整合性を提供。
鍵交換フェーズでは、クライアントはClientHello ( (Section 4.1.2) ) メッセージを送信する。これには、Nonce乱数 (ClientHello.random)、クライアント側から提示されたプロトコル・バージョン、対称暗号/HKDF ハッシュ・ペアのリスト、幾つかのディフィー・ヘルマン鍵共有値 (“key-share”拡張の中のSection 4.2.7)、一つまたは複数の事前共有鍵ラベル (“pre_shared_key”拡張の中の {Section 4.2.10)、または両方、さらに潜在的にその他の拡張。ミドルボックス互換性のために追加フィールドと/またはメッセージも可能。
サーバは ClientHello を処理し、接続のために適切な暗号化パラメータを決定し、調整された接続パラメータ、ServerHello を応答する [Section 4.1.3]。ClientHelloとServerHelloの組み合わせで共有鍵が決定される。(EC)DHEが使用されている場合、ServerHelloは サーバの一時的ディフィー・ヘルマン共有値とともに一つの“key_share”拡張を含む。これは、クライアントの共有値の一つと同じグループに属するものでなければならない (MUST)。PSK鍵確立が使用されている場合、ServerHello はクライアントの提示したPSKのうちどれが選択されたかを示す “pre_shared_key” 拡張を含む。両方の拡張が送られるような場合、インプリメンテーションでは (EC)DHEとPSKを同時に使用することができる点に留意。
次に、サーバは Server Parametersを確立するために二つのメッセージを送信する。
EncryptedExtensions: 個々の証明書に固有のものを除いて、暗号パラメータの決定に必要とされないClientHello拡張に対する応答。[Section 4.3.1]
CertificateRequest: 証明書ベースのクライアント認証が要求された場合、その証明書のために必要とされるパラメータ。クライアント認証が要求されない場合、このメッセージは省略される。 [Section 4.3.2]
最後に、クライアントとサーバは認証メッセージを交換する。TLSは認証が必要な時には常に同じメッセージの集合を使用する。特に:
Certificate.: エンドポイントの証明書および任意の証明前拡張。このメッセージはサーバが証明書による認証をしない場合はサーバ、およびサーバ側からCertificateRequest が送出されなかった(したがって、クライアントは証明書におる認証が不要とみなされる)場合はクライアント側からは省略される。もし生の公開鍵 [RFC7250] またはキャッシュされた情報拡張[RFC7924] が使用される場合、このメッセージは証明書ではなく、サーバの長期鍵(long-term-key)に対応する何らかの値を含む点に留意。[Section 4.4.2]
CertificateVerify.: そのCertificateメッセージ内の公開鍵を使ったハンドシェイク全体の間一つの署名。このメッセージは、サーバが証明書による認証をしていない場合、省略される。[Section 4.4.3]
Finished.: そのハンドシェイク全体に対するMAC値(Message Authentication Code)。このメッセージは鍵の確認、エンドポイントのアイデンティティと交換された鍵への関連づけ、PSKモードに置いてはハンドシェイクの認証を提供する。[Section 4.4.4]
サーバのメッセージの受信で、クライアントは自分の認証メッセージ、単にCertificateとCertificateVerify (要求されていれば) 、およびFinishedを応答する。
この時点で、ハンドシェイクは完了し、クライアントとサーバはアプリケーション層のデータを交換することができる。アプリケーション・データは Finishedメッセージの送信以前に送信されてはならない (MUST NOT)。サーバはクライアントの認証メッセージを受信する前にアプリケーション・データを送信しても良いけれど、その時点で送るデータは、もちろん、認証されていない相手に送られる点に留意。
2.1 不十分なDHE共有
クライアントが充分な “key_share” 拡張を提供しなかった場合 (例えば、サーバが受け入れ不能、またはサポートしていないDHEやECDHEグループしか含まれていない場合)、図2に示すように、サーバは HelloRetryRequestによってミスマッチを訂正し、クライントは適切な “key-share” 拡張でハンドシェイクをリスタートしなければならなくなる。共通の暗号化パラメータがネゴシエートできない場合、サーバは “handshake_failure” または “insufficient_security” 致命的アラートを送信しなければならない(MUST)。
図2:パラメータミスマッチ時のフルハンドシェイクのメッセージ・フロー
ハンドシェイク・トランスクリプトは初期のClientHello/HelloRetryRequestのやりとりを含んでいる。これは新しいClientHello ではない点に留意。
TLS は以下に説明するように、基本ハンドシェイクに対して幾つかの最適化のための変形を許している。
2.2 再開と事前共有鍵 (PSK)
TLS PSK はTLS のスコープ外で確立することも可能だが、PSK は前のセッションで確立しておき、セッション再開 (“session resumption”) することも可能である。一旦ハンドシェイクが完了したら、サーバはクライアントに最初のハンドシェイク ({Section 4.6.1参照) から得られる鍵に対応するPSK識別子をクライアントに送ることができる。クライアントは以後のハンドシェイクでPSKの使用をネゴシエイトするためにそのPSK識別子を使用することができる。もし、サーバがそれを受け入れた場合、新しい接続のセキュリティ・コンテキストはオリジナルの接続に結び付けられる。 TSL1,2およびそれ以前では、この機能は “セッションID” と “ セッション・チケット“RFC5077によって提供されていた。TLS1.3では両者は廃止される。
PSK は、共有鍵と組みわせて前方秘匿性を提供するために (EC)DHE 交換と共に使用することができる。また前方秘匿性を失うコストと引き換えに単体で使用することもできる。
図3は、はじめのPSK確立とその後にそれを使用するハンドシェイクの一対のハンドシェイクを示す。
サーバがPSK経由で認証するときは、Certificate および CertificateVerify メッセージを送信しない。クライアントがPSK経由で再開を求めるときは、 サーバが再開を拒否し必要ならフル・ハンドシェイクにフォールバックできるように、サーバに対して “key_share” 拡張も提供しなければならない (SHOULD)。サーバは PSK鍵確立をネゴシエートするために“pre_shared_key” “拡張で応答し、(ここに示すしように) (EC)DHE鍵確立をするために ”key_share” 拡張で応答することができる。
PSKがプロトコルの範囲側で管理される場合は、PSK IDとPSKと共に使用されるKDFハッシュアルゴリズムも規定されなければならない(MUST)。
注:[RFC4086]で議論されているように、プロトコルの範囲外で管理された事前共有の秘密値を使用する場合は、鍵生成時に十分なエントロピーを使用することが重要な考慮事項である。共有秘密値をパスワードまたは他の低エントロピーのソースから得るのは安全でない。エントロピーの低い秘密値またはパスワードは、PSKバインダーに基づく辞書攻撃の対象となりうる。ディフィ-ヘルマン鍵の設立が使用された場合でも、指定されたPSK認証は強力なパスワードベースの認証された鍵交換とはならない。特に、パスワードないし共有鍵に対するブルートフォース攻撃を実行することでハンドシェイクを観測できる攻撃者に対して防衛できない。
Zero-RTTデータ
クライアントとサーバがPSK(外部か以前のハンドシェイクで得られたもの)を共有する場合、TLS1.3ではクライアントはその最初のフライトでデータを送信することを許す (“early data”)。クライアントはPSKをサーバの認証とEarly dataの復号のために使用する。
図4に示すように、0-RTTデータは単に1-RTTハンドシェイクに最初のフライトが追加されただけである。残りのハンドシェイクは 1-RTTハンドシェイクPSK再開と同じメッセージを使用する。
図4:ゼロ・ラウンドトリップ・ハンドシェイクのためのメッセージ・フロー
重要な注意(IMPORTANT NOTE): 0-RTTのセキュリティ特性はその他のTSLデータのそれらより弱い。特に:
- 受け取ったPSKだけによる鍵で暗号化されているために、このデータは前方秘匿性がない。
- 接続間でリプレイ攻撃で無いことの保証が無い。通常のTLS1.3の1-RTTでははサーバの乱数値によってリプレイ攻撃から防衛しているが、0-RTTデータはServerHelloに依存していないためより弱い保証しかない。特に、データが TLS クライアント認証、もしくはアプリケーション層プロトコルの内側で認証されたかと関連する。同様の警告がearly_exporter_master_secretにもあてはまる。
0-RTTデータは、接続内で重複することはできない(つまり、サーバーは同じ接続で同じデータを2回処理しない)。攻撃者は0-RTTデータを1-RTTデータに見せかけることはできない(異なるキーで保護されているため)。Appendix E.5には、潜在的な攻撃の説明、第8章では、サーバーがリプレイの影響を制限するために使用できるメカニズムについて説明する。