2017-10-07 3 views
0

Je construis un service B2B par Tomcat 8 + Java 8. Mais un de mes clients ne peut pas se connecter à mes services en utilisant SSL. Après avoir ajouté le paramètre de débogage SSL: "-Djavax.net.debug = ssl", je vois les messages d'erreur:Comment résoudre "pas de suites de chiffrement en commun" lors de la négociation 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 

Comment résoudre l'erreur?

Répondre

0

Voici mon partage d'expérience pour résoudre le problème.

  1. Activer le paramètre de débogage SSL "-Djavax.net.debug = ssl", et a trouvé l'erreur est "pas des suites de chiffrement en commun"

  2. Après googler quelques pages, j'ai installé « Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction ", http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html, il a ajouté quelques algorithmes de cryptographie au niveau JVM, ex: TLS_RSA_WITH_AES_256_CBC_SHA, mais il n'a pas résolu le problème. PS. Ciphers.java est un code utile, qui peut afficher les suites de chiffrement disponibles au niveau de la JVM.

  3. J'ai capturé les paquets réseau et analysé dans wireshark, il a montré après que le client a envoyé ClientHello, mon serveur a déconnecté la connexion immédiatement.

  4. Puisque mon client ne peut pas tester avec le mien, je dois reproduire le problème par moi-même pour accélérer le processus de dépannage. Ensuite, j'ai trouvé le code SslPoke.java et l'ai modifié. Il peut simuler la requête du client en utilisant différentes combinaisons de versions TLS ou de suites de chiffrement. Et je peux simuler le même journal d'erreurs par moi-même, cela m'a beaucoup aidé.

  5. Ensuite, Google encore une fois, je trouve que je peux préciser les suites de chiffrement dans le server.xml de Tomcat, ex:

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

J'ai ajouté la config, testé par SslPoke et passé, le cas fermé.

Espérons que l'expérience puisse aider d'autres personnes confrontées au même problème. N'oubliez pas de vérifier les configurations de suites de chiffrements dans JVM/Web Container/App Server ... Et les codes suivants sont également très utiles, merci pour les experts qui les fournissent.

Cordialement,
Leon

code: Ciphers.java, résultat: 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()); 
     } 
    } 
} 

code: SslPoke.java, trouvés à partir de: 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(); 
     } 
    } 
}