2010-12-16 45 views
8

私は完全にここに固執しています。自己署名入りの証明書を持つSSLサーバーに接続する必要があるJavaクライアントコードがあります。自己署名入りの証明書を使用してSSLサーバーに接続しているクライアント

問題は、サーバー側でSSLv2サポートを無効にすると表示されます。

private static DefaultHttpClient createHttpClient(int port) { 
    try { 
     java.lang.System.setProperty(
       "sun.security.ssl.allowUnsafeRenegotiation", "true"); 

     // First create a trust manager that won't care. 
     X509TrustManager trustManager = new X509TrustManager() { 
      public void checkClientTrusted(X509Certificate[] chain, 
        String authType) throws CertificateException { 
       // Don't do anything. 
      } 

      public void checkServerTrusted(X509Certificate[] chain, 
        String authType) throws CertificateException { 
       // Don't do anything. 
      } 

      public X509Certificate[] getAcceptedIssuers() { 
       return new java.security.cert.X509Certificate[0]; 
      } 
     }; 

     // Now put the trust manager into an SSLContext. 
     // Supported: SSL, SSLv2, SSLv3, TLS, TLSv1, TLSv1.1 
     SSLContext sslContext = SSLContext.getInstance("SSLv3"); 
     sslContext.init(null, new TrustManager[] { trustManager }, 
       new SecureRandom()); 

     // Use the above SSLContext to create your socket factory 
     // (I found trying to extend the factory a bit difficult due to a 
     // call to createSocket with no arguments, a method which doesn't 
     // exist anywhere I can find, but hey-ho). 
     SSLSocketFactory sf = new SSLSocketFactory(sslContext); 
     // Accept any hostname, so the self-signed certificates don't fail 
     sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 

     // Register our new socket factory with the typical SSL port and the 
     // correct protocol name. 
     //Scheme httpsScheme = new Scheme("https", sf, port); 
     SchemeRegistry schemeRegistry = new SchemeRegistry(); 
     schemeRegistry.register(new Scheme("https", sf, port)); 

     HttpParams params = new BasicHttpParams(); 
     ClientConnectionManager cm = new SingleClientConnManager(params, 
       schemeRegistry); 

     return new DefaultHttpClient(cm, params); 
    } catch (Exception ex) { 
     Log.error("ERROR Creating SSL Connection: " + ex.getMessage()); 

     return null; 
    } 
} 

トレースは、私は次の痕跡を見ることができ、サーバー側で

trigger seeding of SecureRandom 
done seeding SecureRandom 
keyStore is : 
keyStore type is : jks 
keyStore provider is : 
init keystore 
init keymanager of type SunX509 
trustStore is: /usr/lib/jvm/java-6-openjdk/jre/lib/security/cacerts 
trustStore type is : jks 
trustStore provider is : 
init truststore 
adding as trusted cert: 
x 
x 
x 

trigger seeding of SecureRandom 
done seeding SecureRandom 
2010-12-16 17:25:08,705 [DEBUG][gwt-log][ 5] Connecting: 1 
Allow unsafe renegotiation: true 
Allow legacy hello messages: true 
Is initial handshake: true 
Is secure renegotiation: false 
%% No cached client session 
*** ClientHello, TLSv1 
RandomCookie: GMT: 1292516708 bytes = { 205, 187, 238, 65, 164, 126, 107, 173, 51, 124, 60, 146, 4, 127, 165, 246, 216, 181, 106, 72, 9, 214, 243, 64, 34, 117, 141, 76 } 
Session ID: {} 
Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV] 
Compression Methods: { 0 } 
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1} 
Extension ec_point_formats, formats: [uncompressed] 
*** 
[write] MD5 and SHA1 hashes: len = 177 
0000: 01 00 00 AD 03 01 4D 0A 3D 64 CD BB EE 41 A4 7E ......M.=d...A.. 
xxxxxxx 
00B0: 00             . 
btpool0-0, WRITE: TLSv1 Handshake, length = 177 
[write] MD5 and SHA1 hashes: len = 173 
0000: 01 03 01 00 84 00 00 00 20 00 00 04 01 00 80 00 ........ ....... 
xxxxxxx 
00A0: F6 D8 B5 6A 48 09 D6 F3 40 22 75 8D 4C   [email protected]"u.L 
btpool0-0, WRITE: SSLv2 client hello message, length = 173 
[Raw write]: length = 175 
0000: 80 AD 01 03 01 00 84 00 00 00 20 00 00 04 01 00 .......... ..... 
xxxxxxx 
00A0: 7F A5 F6 D8 B5 6A 48 09 D6 F3 40 22 75 8D 4C  [email protected]"u.L 
btpool0-0, handling exception: java.net.SocketException: Connection reset 
btpool0-0, SEND TLSv1 ALERT: fatal, description = unexpected_message 
btpool0-0, WRITE: TLSv1 Alert, length = 2 
btpool0-0, Exception sending alert: java.net.SocketException: Broken pipe 
btpool0-0, called closeSocket() 
btpool0-0, IOException in getSession(): java.net.SocketException: Connection reset 
2010-12-16 17:25:08,890 [DEBUG][gwt-log][ 6] peer not authenticated 
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated 
    at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:371) 
    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128) 
    at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:399) 
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:143) 
    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149) 
    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:108) 
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:731) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:709) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:700) 

[Fatal Error] :1:1: Premature end of file. 
Finalizer, called close() 
Finalizer, called closeInternal(true) 

です:

info sock48 handshake start {before/accept initialization} 
info sock48 accept loop {before/accept initialization} 
info sock48 accept exit {SSLv3 read client hello B} 
error sock48 {wrong version number} 

私はSSL2を有効にした場合、私は

info sock47 handshake start {before/accept initialization} 
info sock47 accept loop {before/accept initialization} 
info sock47 accept loop {SSLv3 read client hello A} 
info sock47 accept loop {SSLv3 write server hello A} 
info sock47 accept loop {SSLv3 write certificate A} 
info sock47 accept loop {SSLv3 write server done A} 
info sock47 accept loop {SSLv3 flush data} 
info sock47 accept exit {SSLv3 read client certificate A} 
info sock47 accept exit {SSLv3 read client certificate A} 
info sock47 accept loop {SSLv3 read client key exchange A} 
info sock47 accept loop {SSLv3 read finished A} 
info sock47 accept loop {SSLv3 write change cipher spec A} 
info sock47 accept loop {SSLv3 write finished A} 
info sock47 accept loop {SSLv3 flush data} 
info sock47 handshake done {SSL negotiation finished successfully} 
info sock47 accept exit {SSL negotiation finished successfully} 
info sock47 alert write {close notify} 

見てすべて正常に動作します。

また、他のソフトウェアとの接続が問題なく動作するため、サーバー側には何もわかりません。

私は間違って何を考えていますか?

また、この「読者クライアントA/B」の意味を知っている人はいますか? SSLSocketFactoryは、この新しいTLSSocketFactoryで交換する必要があるFIXED

- UPDATE

おかげ

public class TLSSocketFactory extends SSLSocketFactory { 

private final javax.net.ssl.SSLSocketFactory socketfactory; 

public TLSSocketFactory(SSLContext sslContext) { 
    super(sslContext); 

    this.socketfactory = sslContext.getSocketFactory(); 
} 

public Socket createSocket() throws IOException { 
    SSLSocket socket = (SSLSocket) super.createSocket(); 

    socket.setEnabledProtocols(new String[] {"SSLv3, TLSv1"}); 

    return socket; 
} 

public Socket createSocket(
     final Socket socket, 
     final String host, 
     final int port, 
     final boolean autoClose 
    ) throws IOException, UnknownHostException { 

    SSLSocket sslSocket = (SSLSocket) this.socketfactory.createSocket(
      socket, 
      host, 
      port, 
      autoClose 
    ); 

    sslSocket.setEnabledProtocols(new String[] {"SSLv3", "TLSv1"}); 

    getHostnameVerifier().verify(host, sslSocket); 

    return sslSocket; 
} 

}

答えて

5

クライアントで有効なプロトコルの一覧からSSLv2ClientHelloを削除します。

+0

提案していただきありがとうございます。私は、SSLSocketFactoryを拡張し、私がやっているcreateSocketメソッドでMySSLSocketFactoryを作成しました。 sslSocket.setEnabledProtocols(new String [] {"SSLv3"}); しかし私は違いは見ません。 私もSystem.setProperty( "https.protocols"、 "SSLv3")で試しました。 これを行う方法は他にありますか? –

+1

TLSv1をリストに追加していないことがわかりました:) –

+0

@CarlosTasadaこれは私が言ったことではありません。私は*有効なプロトコルのリストから 'SSLv2ClientHello'を削除するように言いました。独自のリストをゼロから定義するのではありません。 – EJP

関連する問題