Transport Layer Security (TLS)再ネゴシエーションの問題

2009年秋に、SSL/TLSプロトコルの問題が見つかりました。 IETF TLS Working Groupによってプロトコルの修正が開発され、JDKの現行バージョンにはこの修正が含まれています。 このセクションでは、このプロトコル修正を含まない以前の実装との通信時における相互運用性の問題を含め、状況をさらに詳しく説明します。

この脆弱性により、選択されたプレーン・テキストを接頭辞としてTLS接続に注入できるというMan-In-The-Middle (MITM)攻撃を許していました。 この脆弱性は、クライアントとサーバーがセッションのネゴシエーションに成功した後、傍受されたネットワーク通信を攻撃者が復号化または変更することを許すものではありません。

詳細は、CVE-2009-3555 (に投稿されたMitre's 「一般的な脆弱性およびエクスポージャ・リスト」、2009)を参照してください。

この問題を解決するためのフェーズ別アプローチ

この問題の修正は、2つのフェーズに分けて扱われています。


ノート: 再ネゴシエーションを必要としないアプリケーションはフェーズ2のデフォルト構成に影響を受けません。 ただし、再ネゴシエーションを必要とするアプリケーション(最初は匿名のクライアント・ブラウズを許可するが、後でSSL/TLS認証済のクライアントを要求するWebサーバーなど)は:


フェーズ2修正の説明

SunJSSE実装は、RFC 5746に準拠したピアへの接続について、再ネゴシエーションをデフォルトで再び有効にします。 つまり、セキュアに再ネゴシエーションを行うためには、クライアントとサーバーが両方ともRFC 5746をサポートする必要があります まだアップグレードされていないピアとの接続について、SunJSSEではある程度の相互運用性モードが提供されていますが、ユーザーがクライアントとサーバーの両方の実装をできるだけ早く更新することを強く推奨します

フェーズ2修正により、SunJSSEは現在3つの再ネゴシエーション相互運用性モードを用意しています。 どのモードもRFC 5746のセキュアな再ネゴシエーションを完全にサポートしていますが、アップグレードされていないピアと通信する場合、次のような意味合いが加わります。

3つのモード区分は、アップグレードされていないピアとの接続にのみ影響します。 すべてのクライアントおよびサーバーで厳密モード(完全なRFC 5746モード)を使用することが望ましいのですが、配備されているすべてのSSL/TLS実装がRFC 5746をサポートするようになるまである程度時間がかかるため、今のところは相互運用モードがデフォルトになっています。

次の表には、クライアントおよび/またはサーバーがRFC 5746をサポートするように更新されるかどうかのさまざまな場合のモードに関する相互運用性情報が含まれています。

相互運用性情報
Client Server モード
更新しました 更新しました

すべてのモードで再ネゴシエーションがセキュリティ保護されます。

レガシー 脚注1 更新しました
更新しました レガシー 脚注1
  • 厳密
    サーバーが正しいRFC 5746メッセージで応答しない場合、クライアントは接続をすぐに切断します(SSLHandshakeExceptionまたはhandshake_failure)。
  • 相互運用可能
    レガシー・サーバーからの初期接続(RFC 5746メッセージが欠落している)は許可されますが、再ネゴシエーションはサーバーによって許可されません。
    脚注2 脚注3
  • セキュアでない
    レガシー・サーバーとの接続および再ネゴシエーションは許可されますが、元のMITM攻撃に対して脆弱です。
レガシー 脚注1 レガシー 脚注1 既存のSSL/TLS動作を行い、MITM攻撃に対して脆弱です。

脚注1 「レガシー」とは元のSSL/TLS仕様を意味します(つまり、RFC 5746でない)。

脚注2 SunJSSEフェーズ1実装は、明示的に再有効化されないかぎり再ネゴシエーションを拒否します。 再ネゴシエーションが再有効化された場合、それらは正しいRFC 5746メッセージを送信しないため、RFC 5746に準拠したピアによって「レガシー」として扱われます。

脚注3 SSL/TLSでは、再ネゴシエーションをいずれの側からでも開始できます。 フェーズ1修正のように、アップグレードされていないピアと相互運用モードで通信しているアプリケーションが(SSLSocket.startHandshake()またはSSLEngine.beginHandshake()を使用して)再ネゴシエーションを開始しようとすると、アプリケーションはSSLHandshakeException (IOException)を受け取り、接続は停止されます(handshake_failure)。 まだアップグレードされていないピアから再ネゴシエーション要求を受け取ったアプリケーションは、現在の接続のタイプに応じて応答します。

モードを設定するために、次のシステム・プロパティを使用します。

相互運用性モードを設定するためのシステム・プロパティの値
モード allowLegacyHelloMessages allowUnsafeRenegotiation
厳格 false false
相互運用(デフォルト) true false
安全でない true true

注意: セキュアでないSSL/TLS再ネゴシエーションは、脆弱性が再確立されるため、再有効化しないでください。


システム・プロパティを設定することによって特定のモードを構成する方法については、「java.lang.Systemプロパティの設定方法」を参照してください。

SSL/TLS再ネゴシエーションに対する回避方法と代替方法

すべてのピアは、できるだけ早くRFC 5746準拠の実装に更新する必要があります。 このRFC 5746修正を適用しても、再ネゴシエーションが必要な場合は、アップグレードされていないピアとの通信に影響が生じます。 推奨されるいくつかの方法を次に示します。

実装の詳細

RFC 5746では2つの新しいデータ構造が定義されており、上級ユーザーのために、ここで説明します。

これらのいずれも、実装がRFC 5746に準拠していることと、セキュアな再ネゴシエーションが実行できることを通知するために使用できます。 関連する技術的な議論については、2009年11月から2010年2月までのIETFの電子メールによる議論を参照してください。

RFC 5746により、クライアントは最初のClientHelloでSCSVまたはRIを送信できます。 相互運用性を最大限に高めるため、SunJSSEはデフォルトでSCSVを使用しますが、これは、いくつかのTLSサーバー/SSLサーバーが不明な拡張機能を正しく処理できないためです。 有効化された暗号化方式群(SSLSocket.setEnabledCipherSuites()またはSSLEngine.setEnabledCipherSuites())にSCSVが存在することによって、最初のClientHello内でSCSVを送信するか、あるいはRIをかわりに送信すべきかどうかが判別されます。

SSLv2はSSL/TLS拡張機能をサポートしません。 SSLv2Helloプロトコルが有効化された場合、SCSVが最初のClientHello内で送信されます。

フェーズ1修正の説明

前述のとおり、フェーズ1修正は、RFC 5746に準拠した修正が開発されるまでの間、再ネゴシエーションをデフォルトで無効にするためのものでした。 再ネゴシエーションは、sun.security.ssl.allowUnsafeRenegotiationシステム・プロパティを設定することによって再び有効化できました。 フェーズ2修正では同じsun.security.ssl.allowUnsafeRenegotiationシステム・プロパティを使用するだけでなく、それにRFC 5746メッセージを使用させる必要もあります。

すべてのアプリケーションを、できるだけ早くフェーズ2 RFC 5746修正にアップグレードする必要があります。

SSL/TLS再ネゴシエーションにおける安全でないサーバー証明書の変更の許可

次の場合、SSL/TLS再ネゴシエーションでサーバー証明書を変更することは、安全でないことがあります。

  1. エンドポイント識別がSSL/TLSハンドシェークで有効でない場合、および
  2. 以前のハンドシェークがセッション再開省略初期ハンドシェークである場合、および
  3. 両方の証明書によって表されるアイデンティティが同じと見なせる場合。

2つの証明書は、次の場合に、同じアイデンティティを表すと見なせます。

  1. IPアドレスのサブジェクトの代替名が両方の証明書に存在する場合、同一であるはずです。または、
  2. DNS名のサブジェクトの代替名が両方の証明書に存在する場合、同一であるはずです。または、
  3. サブジェクト・フィールドが両方の証明書に存在する場合、証明書のサブジェクトと発行人は同一であるはずです。

JDK 8u25以降では、SSL/TLS再ネゴシエーションでの安全でないサーバー証明書の変更は、デフォルトでできません。 新しいシステム・プロパティjdk.tls.allowUnsafeServerCertChangeを使用して、SSL/TLS再ネゴシエーションにおける安全でないサーバー証明書の変更を制限するかどうかを定義できます。

このシステム・プロパティのデフォルト値はfalseです。


注意: どうしても必要でないかぎり、このシステム・プロパティを"true"に設定しないでください。安全でないサーバー証明書変更の脆弱性が再び確立される可能性があります。



Copyright © 1993, 2025, Oracle and/or its affiliates. All rights reserved.