web-dev-qa-db-ja.com

JavaのSSLSocketがバージョン2のクライアントにHelloを送信するのはなぜですか?

SSLSocket.getEnabledProtocols()メソッドは、_[SSLv2Hello, SSLv3, TLSv1]_を返します。実際、connect()を呼び出し、SSLデバッグをオンにすると、v2クライアントのHelloが使用されていることがわかります。

_main, WRITE: TLSv1 Handshake, length = 81
main, WRITE: SSLv2 client hello message, length = 110
_

しかし、JSSEがSSLバージョン2をサポートしているとは言えないという2つの(確かに古い)参照を見つけました。

From Javaの基本的なネットワーキング

'SSLv2Hello'は、JavaがSSLv2 'helloメッセージ'を使用してハンドシェイクを開始できるようにする疑似プロトコルです。これにより、SSLv2プロトコルが使用されますnot Javaはまったくサポートしていません。

そして JSSEリファレンスガイド から:

J2SDK 1.4以降のJSSE実装は、SSL 3.0およびTLS 1.0を実装しています。 SSL 2.0は実装されていません。

今、私の理解は、バージョン2.0のクライアントhelloは、クライアントがSSLバージョン2.0をサポートしている場合にのみ送信する必要があることです。から RFC 2246

SSLバージョン2.0サーバーをサポートするTLS 1.0クライアントは、SSLバージョン2.0クライアントのhelloメッセージを送信する必要があります[SSL2] ...警告:バージョン2.0クライアントを送信する機能こんにちはメッセージはすべての速攻で段階的に廃止されます。

では、なぜJavaを使用するのですか?

23
Matt Solnit

SunのJSSEはSSLv2をサポートしていませんが、SSLv2を必要とする一部のSSLサーバーをサポートするためにSSlv2ClientHelloをサポートしています。有効になっているプロトコルから削除することでオフにすることができます。

IBMのJSSEはSSLv2を完全にサポートしています。

JSSEリファレンスガイド から:

たとえば、一部の古いサーバー実装はSSLv3のみを話し、TLSを理解しません。理想的には、これらの実装はSSLv3にネゴシエートする必要がありますが、一部は単にハングアップします。下位互換性のために、一部のサーバー実装(SunJSSEなど)は、SSLv2 ClientHelloパケットにカプセル化されたSSLv3/TLS ClientHelloを送信します。一部のサーバーはこの形式を受け入れません。これらの場合、setEnabledProtocolsを使用して、カプセル化されたSSLv2 ClientHelloの送信を無効にします。

「サーバーの実装」は上記の「SSLの実装」を読むべきだと思います。

編集:私の本を引用してくれてありがとう!

18
user207421