2009-12-21 60 views
2

我試圖讓我的Java客戶端與使用SSL的C服務器進行通信。SSLSockets和密碼規格問題

的問題是 - 我沒有任何的服務器源,我得到一個握手失敗錯誤:

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 

一些重型Wireshark操作我現在知道後,該工作C客戶端(我不噸訪問他們的源代碼既不)具有在客戶端 - 服務器的hello分組這些密碼規格:

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) 

和所有報文中的SSLv2協議發送。

而這些都是從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 

現在我想用

Cipher Spec: SSL2_RC4_128_WITH_MD5 (0x010080) 

,因爲它似乎是用C服務器均支持我的Java客戶端。所以,我想出了這個代碼:

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(); 

但由於某些原因,這些密碼規範在客戶端發送Hello報文:

Cipher Spec: TLS_RSA_WITH_RC4_128_MD5 (0x000004) 
Cipher Spec: SSL2_RC4_128_WITH_MD5 (0x010080) 

不應該有隻包括第二個? 這會導致服務器以TLSv1協議發送server-hello數據包,並導致握手失敗。

我又試圖找出發生了什麼:

這些都是支持的協議,我從getSupportedProtocols()有:

SSLv2Hello 
SSLv3 
TLSv1 

如果我把這樣的事情在我的代碼:

sslsocket.setEnabledProtocols(new String[] { "SSLv2Hello" }); 

它說:

Exception in thread "main" java.lang.IllegalArgumentException: SSLv2Hellocannot be enabled unless TLSv1 or SSLv3 is also enabled 

如果我切換到:

sslsocket.setEnabledProtocols(new String[] { "SSLv2Hello", "SSLv3" }); 

服務器答案在SSLv3和我得到的握手失敗...

原來是這樣,我不知道如何得到這個工作,任何幫助嗎?

是否有可能,SSLv2不再支持,我只是不能使用它與Java?

回答

1

JDK JSSE提供程序不支持SSL v2,這是一種固有的不安全協議。 SSLv2Hello支持旨在與可能存在協議錯誤並需要v2 hello的某些服務器的SSLv3兼容。這個SSLv2Hello在JDK7中被刪除。

對於實際對話,僅支持SSLv3和TLS。因此,如果您的服務器僅支持SSL v2,則需要升級服務器 - v2不安全,不應使用。

SSL_RSA_WITH_RC4_128_MD5TLS_RSA_WITH_RC4_128_MD5是相同的密碼套件,但熱點JSSE當通過SSLSocketFactory.getSupportedCipherSuites()要求的支持套件集,只報告了前者。當前的Wireshark協議分析器會報告TLS_RSA_WITH_RC4_128_MD5 (0x0004),這可能會導致混淆。

參見:

How to initiate ssl connection using SSLv2 http://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html

編輯:因爲我提到的SSLv2以上是非常過時和沒有安全感,我覺得我現在還應該提到的是,由於SSLv3 POODLE exploit已經公佈,在SSLv3也被認爲不安全並被棄用。