2 Stimmen

SSLSockets und Problem mit Cipher Specs

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?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X