web-dev-qa-db-ja.com

TLS 1.1+ ClientHelloメッセージのバージョンフィールドの意味は何ですか?

すでにTLS 1.0をサポートしているパケットキャプチャ製品にTLS 1.1および1.2のサポートを追加しようとしています。

Wiresharkを使用して、ブラウザーとopensslサーバー間のトラフィックをキャプチャし、いくつかのテストケースを生成しました。作成したすべてのトレースで予期しないTLSバージョンが流れるのを見ました。

Secure Sockets Layer
    TLSv1.2 Record Layer: Handshake Protocol: Client Hello
        Content Type: Handshake (22)
        Version: TLS 1.0 (0x0301)
        Length: 105
        Handshake Protocol: Client Hello
            Handshake Type: Client Hello (1)
            Length: 101
            Version: TLS 1.2 (0x0303)

上記は、Wiresharkによって報告されたTLS 1.2トレースの1つからの抜粋です。指定されたバージョンは、ClientHelloのTLS 1.0と後続のすべてのメッセージの1.2です。これは、TLS 1.1と1.2の両方のトレースで発生しました。

付録E.1。 (TLS 1.0/1.1およびSSL 3.0との互換性)TLS 1.2 RFCによると、

Earlier versions of the TLS specification were not fully clear on
what the record layer version number (TLSPlaintext.version) should
contain when sending ClientHello (i.e., before it is known which
version of the protocol will be employed).  Thus, TLS servers
compliant with this specification MUST accept any value {03,XX} as
the record layer version number for ClientHello.

それ自体も少しあいまいです。

だから私の質問は:

  • このフィールドは完全に任意の値にすることができますか(SSLv3以上であれば)?
  • このフィールドで指定されたバージョンによって動作は変わりますか?
  • ブラウザがSSLv3ではなくTLS 1.0を選択することに何らかの意味がありますか?

関連:

  • https://security.stackexchange.com/a/26059/7866 この回答は、相互運用性を最大限に高めるために、SSLv3をClientHelloで使用する必要があることを示唆しています。相互運用性の言及は、サーバーがどのような値が与えられるかを気にすることを意味します。
13
Burhan Ali

バージョンフィールドは3つの場所で発生します。

  • クライアントとサーバーが送信する各recordのヘッダーの一部として;
  • クライアントからのClientHelloメッセージの一部として。
  • サーバーからのServerHelloメッセージの一部として。

プロトコルバージョンネゴシエーション

ClientHelloのバージョンフィールドは、クライアント実装でサポートされる最大バージョンです。たとえば、クライアントがこのフィールドに0x0302(これは「TLS 1.1」を意味する従来の値です)を入力すると、クライアントに「TLS 1.1までのすべてのプロトコルバージョンを処理する準備ができました」とサーバーに伝えます。サーバーからのServerHelloメッセージのバージョンフィールドは、この接続に使用されるプロトコルバージョンを指定します。サーバーは、クライアントとサーバーの両方がサポートする最高のプロトコルバージョンを使用する必要があります

クライアントが実際にサポートしていないプロトコルバージョンのサポートを発表しないでください。サーバーがそのようなバージョンを選択して、クライアントが実際にサポートしていると誤って信じないようにしてください。

レコードについて

クライアントからのClientHelloは、1つまたは複数のレコードにラップされて送信され、各レコードにはプロトコルバージョンも含まれます。レコードは封筒のようなものです。 ClientHelloに示されているサポートされている最大バージョンに関係なく、これらのレコードにはバージョン0x0300(SSLv3)を使用しても安全です。これはSSLv3エンベロープで手紙を送るようなものですが、手紙には「ところで、TLS 1.0とTLS 1.1もサポートしている」と書かれています。 SSLv3レコードを使用すると、SSLv3のみを認識しており、より高いバージョンのレコードを拒否する古い実装やバグの多い実装との相互運用性が最大化されます。

サーバーからの応答は、使用されるプロトコルのバージョンを示しており、そのバージョンを記したレコードとして来るはずです。例えば。サーバーがそのServerHelloで「TLS 1.1」と言う場合、そのServerHelloも「TLS 1.1」としてタグ付けされたレコードにラップされる必要があります。クライアントとサーバーの両方からの後続のすべてのレコードは、そのバージョンを使用する必要があります。

相互運用性

理論的には、サーバーはバージョンフィールドで0x0300以上の任意の値を受け入れる必要があります。 0xA7C0(「TLS 165.193」を意味します。これはおそらく定義されない架空のバージョンです)。これは、ClientHelloメッセージとレコードヘッダーの両方に当てはまります。プロトコルバージョンはレコードのエンコードに影響しますが、最初のレコードはクリアテキスト(暗号化なし)であり、クリアテキストはクリアテキストであるため、バージョンは無視できます(SSL 3.0、TLS 1.0、TLS 1.1およびTLS 1.2クリアテキストレコードは、ヘッダーで指定されたバージョンですが、それ以外は同じです)。

実際には、最初のバイトが0x03ではない「バージョン」フィールドを許容しない、広く展開されている実装のレポートがあります。 0x0301(別名TLS 1.0)より高いバージョンを指定するClientHelloをサポートしない実装もあります。

問題を最小限に抑えるために、クライアントは次のことを行います。

  • ClientHelloのレコードでSSL 3.0を使用するものとします。
  • ClientHelloでサポートされている最も高いバージョンを指定する必要があります。
  • 失敗した場合、フォールバックしてClientHelloを再試行する可能性があります。今回は、サポートされている最大バージョンが低いと主張します(「TLS 1.1」または「TLS 1.2」が表示されたときにストロークを取得する古いサーバーに対応します)。
21
Tom Leek