2017-10-07 95 views
0

我正在通過Tomcat 8 + Java 8構建B2B服務。 但是我的一位客戶無法使用SSL連接到我的服務。 「-Djavax.net.debug = SSL」,我看到錯誤消息:如何在SSL握手期間解決「不共享密碼套件」?

Is initial handshake: true 
Is secure renegotiation: false 
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 for TLSv1 
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 for TLSv1 
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1 
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1 
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 for TLSv1.1 
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 for TLSv1.1 
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1 
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1 
https-jsse-nio-8445-exec-9, READ: SSLv3 Handshake, length = 62 
*** ClientHello, TLSv1 
RandomCookie: GMT: 1490342314 bytes = { 192, 161, 228, 31, 66, 175, 222, 13, 79, 128, 217, 81, 18, 152, 169, 58, 114, 35, 201, 201, 147, 74, 131, 2, 213, 145, 181, 76 } 
Session ID: {} 
Cipher Suites: [SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, Unknown 0xff:0x3, SSL_RSA_WITH_RC4_128_MD5] 
Compression Methods: { 0 } 
Extension renegotiation_info, renegotiated_connection: <empty> 
*** 
%% Initialized: [Session-7, SSL_NULL_WITH_NULL_NULL] 
https-jsse-nio-8445-exec-9, fatal error: 40: no cipher suites in common 
javax.net.ssl.SSLHandshakeException: no cipher suites in common 

如何解決錯誤 添加SSL調試參數後?

回答

0

以下是我的經驗分享解決問題。

  1. 啓用SSL調試參數「-Djavax.net.debug = SSL」,發現錯誤是「沒有共同的密碼套件」

  2. google搜索一些網頁後,我安裝了「Java加密擴展(JCE)無限強度管轄權「,http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html,它在JVM級別添加了一些密碼算法,例如:TLS_RSA_WITH_AES_256_CBC_SHA,但它沒有解決問題。 PS。 Ciphers.java是一個有用的代碼,它可以顯示JVM級別的可用密碼套件。

  3. 我捕獲了網絡數據包並在wireshark中分析,它顯示客戶端發送ClientHello後,我的服務器立即斷開連接。

  4. 由於我的客戶無法用我的測試,我必須自己重現問題以加快故障排除過程。然後我找到了代碼SslPoke.java並對其進行了修改。它可以通過使用TLS版本或密碼套件的不同組合來模擬客戶端的請求。我可以自己模擬相同的錯誤日誌,它幫助了很多。

  5. 然後,再次谷歌,我發現我可以在Tomcat的server.xml中指定的密碼套件,例如:

<Connector port="${https.port}" SSLEnabled="true" scheme="https" sslProtocol="TLS" ciphers="TLS_RSA_WITH_AES_256_CBC_SHA256... " />

我增加了配置,通過SslPoke測試並通過的情況下關閉。

希望這種體驗能夠幫助其他面臨同樣問題的人。 不要忘記檢查JVM/Web容器/應用程序服務器中的密碼套件配置... 以下代碼也非常有用,感謝提供它們的專家。

最好的問候,
萊昂

代碼:https://confluence.atlassian.com/bitbucketserverkb/list-ciphers-used-by-jvm-779171661.html

public class Ciphers 
{ 
    public static void main(String[] args) 
     throws Exception 
    { 
     SSLServerSocketFactory ssf = (SSLServerSocketFactory)SSLServerSocketFactory.getDefault(); 

     String[] defaultCiphers = ssf.getDefaultCipherSuites(); 
     String[] availableCiphers = ssf.getSupportedCipherSuites(); 

     TreeMap ciphers = new TreeMap(); 

     for(int i=0; i<availableCiphers.length; ++i) 
      ciphers.put(availableCiphers[i], Boolean.FALSE); 

     for(int i=0; i<defaultCiphers.length; ++i) 
      ciphers.put(defaultCiphers[i], Boolean.TRUE); 

     System.out.println("Default\tCipher"); 
     for(Iterator i = ciphers.entrySet().iterator(); i.hasNext();) { 
      Map.Entry cipher=(Map.Entry)i.next(); 

      if(Boolean.TRUE.equals(cipher.getValue())) 
       System.out.print('*'); 
      else 
       System.out.print(' '); 

      System.out.print('\t'); 
      System.out.println(cipher.getKey()); 
     } 
    } 
} 

代碼:Ciphers.java,從發現https://gist.github.com/4ndrej/4547029

public class SslPoke { 

    private static javax.net.ssl.SSLSocketFactory getFactorySimple() throws Exception { 
     SSLContext context = SSLContext.getInstance("TLSv1"); 

     context.init(null, null, null); 

     return context.getSocketFactory(); 

    } 

    public static void main(String[] args) { 
     System.getProperties().setProperty("javax.net.debug", "ssl"); 
     System.getProperties().setProperty("https.cipherSuites", "TLS_RSA_WITH_AES_256_CBC_SHA"); 

     try { 
      String urlStr ="https://<your host>:<your port>"; 
      URL url = new URL(urlStr); 

      HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); 

      javax.net.ssl.SSLSocketFactory sslSocketFactory = getFactorySimple(); 

      connection.setSSLSocketFactory(sslSocketFactory); 
      InputStream in = connection.getInputStream(); 

      while (in.available() > 0) { 
       System.out.print(in.read()); 
      } 
      System.out.println("Successfully connected"); 

     } catch (Exception exception) { 
      exception.printStackTrace(); 
     } 
    } 
} 
:SslPoke.java,從發現
相關問題