Ich versuche, meinen Java-Client dazu zu bringen, mit einem C-Server über SSL zu kommunizieren.
Das Problem ist, dass ich keine Server-Quellen habe und einen Fehler beim Handshake erhalte:
Exception in thread "main" javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1657)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:932)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1096)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1123)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1107)
at posslu.Main.main(Main.java:36)
Java Result: 1
Nach einigem Wiresharking weiß ich nun, dass funktionierende C-Clients (ich habe auch keinen Zugriff auf deren Quellcode) diese Cipher-Specs in Client-Server-Helo-Paketen haben:
Cipher Spec: SSL2_DES_192_EDE3_CBC_WITH_MD5 (0x0700c0)
Cipher Spec: SSL2_IDEA_128_CBC_WITH_MD5 (0x050080)
Cipher Spec: SSL2_RC2_CBC_128_CBC_WITH_MD5 (0x030080)
Cipher Spec: SSL2_RC4_128_WITH_MD5 (0x010080)
Cipher Spec: SSL2_RC4_64_WITH_MD5 (0x080080)
Cipher Spec: SSL2_DES_64_CBC_WITH_MD5 (0x060040)
Cipher Spec: SSL2_RC2_CBC_128_CBC_WITH_MD5 (0x040080)
Cipher Spec: SSL2_RC4_128_EXPORT40_WITH_MD5 (0x020080)
und alle Pakete werden im SSLv2-Protokoll gesendet.
Und dies sind die Spezifikationen der Methode SSLSocket.getSupportedCipherSuites():
SSL_RSA_WITH_RC4_128_MD5
SSL_RSA_WITH_RC4_128_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_128_CBC_SHA
SSL_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
SSL_RSA_WITH_NULL_MD5
SSL_RSA_WITH_NULL_SHA
SSL_DH_anon_WITH_RC4_128_MD5
TLS_DH_anon_WITH_AES_128_CBC_SHA
SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
SSL_DH_anon_WITH_DES_CBC_SHA
SSL_DH_anon_EXPORT_WITH_RC4_40_MD5
SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
TLS_KRB5_WITH_RC4_128_SHA
TLS_KRB5_WITH_RC4_128_MD5
TLS_KRB5_WITH_3DES_EDE_CBC_SHA
TLS_KRB5_WITH_3DES_EDE_CBC_MD5
TLS_KRB5_WITH_DES_CBC_SHA
TLS_KRB5_WITH_DES_CBC_MD5
TLS_KRB5_EXPORT_WITH_RC4_40_SHA
TLS_KRB5_EXPORT_WITH_RC4_40_MD5
TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA
TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5
Jetzt möchte ich
Cipher Spec: SSL2_RC4_128_WITH_MD5 (0x010080)
da es anscheinend sowohl vom C-Server als auch von meinem Java-Client unterstützt wird. So kam ich mit diesem Code:
SSLSocketFactory sslsockfact = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsockfact.createSocket( args[0], args[1] );
sslsocket.setEnabledCipherSuites( new String[] { "SSL_RSA_WITH_RC4_128_MD5" } );
sslsocket.startHandshake();
Aber aus irgendeinem Grund werden diese Verschlüsselungsspezifikationen im Client-Helo-Paket gesendet:
Cipher Spec: TLS_RSA_WITH_RC4_128_MD5 (0x000004)
Cipher Spec: SSL2_RC4_128_WITH_MD5 (0x010080)
Sollte nicht nur die zweite enthalten sein? Dies führt dazu, dass der Server das server-hello-Paket im TLSv1-Protokoll sendet und ich einen Handshake-Fehler erhalte.
Ich habe weiter versucht, herauszufinden, was passiert ist:
Dies sind die unterstützten Protokolle, die ich mit getSupportedProtocols() ermittelt habe:
SSLv2Hello
SSLv3
TLSv1
Wenn ich etwas wie dieses in meinen Code einfüge:
sslsocket.setEnabledProtocols( new String[] { "SSLv2Hello" } );
Dort steht:
Exception in thread "main" java.lang.IllegalArgumentException: SSLv2Hellocannot be enabled unless TLSv1 or SSLv3 is also enabled
Wenn ich zu wechseln:
sslsocket.setEnabledProtocols( new String[] { "SSLv2Hello", "SSLv3" } );
Der Server antwortet mit SSLv3 und ich erhalte einen Handshake-Fehler...
So, das war's. Ich habe keine Ahnung, wie man das zum Laufen bringt.
Ist es möglich, dass SSLv2 nicht mehr unterstützt wird und ich es einfach nicht mit Java verwenden kann?