付録E. 後方互換性 (Backward Compatibility)
本付録では、TLS 1.2と以前のバージョン間の互換性の問題について説明します。
E.1. TLS 1.0/1.1およびSSL 3.0との互換性 (Compatibility with TLS 1.0/1.1 and SSL 3.0)
新機能といくつかの構造的変更のため、TLS 1.2とTLS 1.1、TLS 1.0、SSL 3.0の間には直接の相互運用性はありません。ただし、TLS 1.2には、TLS 1.2実装が以前のバージョンと交渉できるメカニズムが含まれています。
E.1.1. バージョン交渉
TLSは、ハンドシェイクの一部としてバージョン交渉のための組み込みメカニズムを提供します:
-
ClientHelloのバージョン:
- クライアントはClientHelloでサポートする最高バージョンを示します
- 実装はClientHelloでTLS 1.2 (バージョン 3) を示すべきです (SHOULD)
-
ServerHelloのバージョン:
- サーバーは自身とクライアントの両方がサポートする最高バージョンを選択します
- サーバーがクライアントが提案したバージョンをサポートしていない場合、より低いバージョンを選択します
-
レコード層バージョン:
- ClientHelloレコードのバージョンは、最大の互換性のために 1 (TLS 1.0) に設定すべきです (SHOULD)
- 後続のレコードは交渉されたバージョンを使用します
E.1.2. 拡張
TLS 1.2は新しい拡張と既存の拡張への変更を導入しました:
- signature_algorithms拡張: TLS 1.2クライアントはこの拡張を含めなければなりません (MUST)
- 旧バージョンのサーバーは理解できない拡張を無視します
E.1.3. 暗号スイート
特定の暗号スイートはTLS 1.2に固有です:
- SHA-256 PRFを使用する暗号スイート
- 新しいAEAD暗号スイート
以前のバージョンと交渉する際、これらの暗号スイートはClientHelloで提供すべきではありません (SHOULD NOT)。
E.1.4. 実装推奨事項
クライアント実装は以下を行うべきです (SHOULD):
- 複数のTLSバージョンをサポートする
- ClientHelloで最高のサポートバージョンを通知する
- より低いバージョンを受け入れる準備をする
- バージョンフォールバック保護 (SCSV) を実装する
サーバー実装は以下を行うべきです (SHOULD):
- 広範な互換性のために複数のTLSバージョンをサポートする
- 最高のプロトコルバージョンを優先する
- 以前のバージョンのClientHelloを適切に処理する
交渉フローの例:
クライアント (TLS 1.2, 1.1, 1.0をサポート)
-> ClientHello (version=3.3)
サポートバージョン: TLS 1.2, 1.1, 1.0
サーバー (TLS 1.1, 1.0のみサポート)
<- ServerHello (version=3.2)
選択: TLS 1.1
接続はTLS 1.1を使用して続行
E.2. SSL 2.0との互換性 (Compatibility with SSL 2.0)
SSL 2.0は新しい実装では使用すべきではありません (SHOULD NOT)。ただし、レガシーシステムとの互換性のために、一部の実装ではSSL 2.0形式のClientHelloを理解する必要がある場合があります。
E.2.1. SSL 2.0 ClientHello
SSL 2.0 ClientHelloは異なる形式を持ちます:
uint16 msg_length; /* 最上位ビットは1でなければなりません (MUST) */
uint8 msg_type; /* 1でなければなりません (MUST) */
Version version; /* クライアントが希望するバージョン */
uint16 cipher_spec_length; /* 0であってはなりません */
uint16 session_id_length; /* 0または16でなければなりません (MUST) */
uint16 challenge_length; /* 0であってはなりません */
CipherSpec cipher_specs[...];
SessionID session_id;
Challenge challenge;
E.2.2. SSL 2.0 ClientHelloの処理
TLS 1.2サーバーはSSL 2.0形式でカプセル化されたClientHelloを受け入れてもかまいません (MAY) が、以下を行わなければなりません (MUST):
- msg_lengthの最上位ビットを確認する
- 形式の妥当性を検証する
- 処理のためにTLS形式に変換する
- TLS形式のServerHelloで応答する
E.2.3. セキュリティに関する考慮事項
重要: SSL 2.0形式のClientHelloをサポートすることは、SSL 2.0プロトコル自体をサポートすることを意味しません。SSL 2.0には多くの既知のセキュリティ脆弱性があり、使用のために交渉してはなりません (MUST NOT)。
E.2.4. 実装推奨事項
- TLS 1.2クライアントはSSL 2.0形式のClientHelloを送信してはなりません (MUST NOT)
- SSL 2.0形式のClientHelloに対するサーバーのサポートは、現在はしてもかまいません (MAY) であり、すべきです (SHOULD) ではありません
- SSL 2.0形式のClientHelloの送信はすべきではありません (SHOULD NOT)
- 将来のTLSバージョンでは、これをサポートすべきではない (SHOULD NOT) に変更する可能性があります
E.3. 中間者によるバージョンロールバックの回避 (Avoiding Man-in-the-Middle Version Rollback)
プロトコルの以前のバージョンは、攻撃者が接続を以前の (より弱い) プロトコルバージョンの使用を強制できるバージョンロールバック攻撃に対して脆弱でした。
E.3.1. 保護メカニズム
TLS 1.2は、バージョンロールバックを防ぐために複数のメカニズムを使用します:
-
Finishedメッセージ検証:
- Finishedメッセージにはすべてのハンドシェイクメッセージのハッシュが含まれます
- ClientHelloとServerHelloのバージョンフィールドを含みます
- バージョンの変更はFinished検証を失敗させます
-
TLS_FALLBACK_SCSV:
- RFC 7507で定義されたSignaling Cipher Suite Value
- クライアントはより低いバージョンで接続を再試行するときにこの値を含めます
- サーバーはより高いバージョンをサポートしている場合、接続を拒否します
E.3.2. 実装要件
クライアントは以下を行わなければなりません (MUST):
- 以前に試行したバージョンを記録する
- ダウングレード再試行時にTLS_FALLBACK_SCSVを含める
- Finishedメッセージを検証する
サーバーは以下を行わなければなりません (MUST):
- TLS_FALLBACK_SCSVを確認する
- より高いバージョンをサポートしている場合、inappropriate_fallbackアラートを送信する
- Finishedメッセージを正しく計算および検証する
E.3.3. シナリオ例
通常の接続:
クライアント -> ClientHello (TLS 1.2)
サーバー <- ServerHello (TLS 1.2)
... 通常のハンドシェイク ...
成功!
正当なダウングレード:
クライアント -> ClientHello (TLS 1.2)
サーバー <- ServerHello (TLS 1.1)
... TLS 1.1ハンドシェイク ...
成功!
検出された攻撃:
クライアント -> ClientHello (TLS 1.2)
攻撃者が (TLS 1.0) に変更
サーバー <- ServerHello (TLS 1.0)
... ハンドシェイク続行 ...
クライアント -> Finished (検証失敗!)
接続中止!
SCSVでの再試行:
クライアント -> ClientHello (TLS 1.2) - 失敗
クライアント -> ClientHello (TLS 1.1, TLS_FALLBACK_SCSV)
サーバーはSCSVを検出し、TLS 1.2をサポート
サーバー <- Alert: inappropriate_fallback
接続中止 - ダウングレード攻撃を検出!
注記: 完全な互換性情報と詳細な説明については、RFC 5246付録Eの完全なテキストを参照してください。