web-dev-qa-db-fra.com

javax.net.ssl.SSLHandshakeException: connexion fermée avec l'hôte distant lors de l'établissement de la liaison lors de la communication avec le service Web

J'obtiens javax.net.ssl.SSLHandshakeException: connexion fermée avec un hôte distant pendant la négociation exception lorsque j'essaie de faire une publication HTTPS d'un service Web via Internet. Mais le même code fonctionne pour d'autres services Web hébergés sur Internet. J'ai essayé beaucoup de choses, rien ne m'aide. J'ai posté mon exemple de code ici. Quelqu'un peut-il m'aider s'il vous plaît à résoudre ce problème?

public static void main(String[] args) throws Exception {

    String xmlServerURL = "https://example.com/soap/WsRouter";
    URL urlXMLServer = new URL(xmlServerURL);
    // URLConnection supports HTTPS protocol only with JDK 1.4+ 
    Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(
            "xxxx.example.com", 8083));
    HttpURLConnection httpsURLConnection = (HttpURLConnection) urlXMLServer
            .openConnection(proxy);
    httpsURLConnection.setRequestProperty("Content-Type","text/xml; charset=utf-8");
    //httpsURLConnection.setDoInput(true);
    httpsURLConnection.setDoOutput(true);
    httpsURLConnection.setConnectTimeout(300000);
    //httpsURLConnection.setIgnoreProxy(false);
    httpsURLConnection.setRequestMethod("POST"); 
    //httpsURLConnection.setHostnameVerifier(DO_NOT_VERIFY); 
    // send request
    PrintWriter out = new PrintWriter(
            httpsURLConnection.getOutputStream());
    StringBuffer requestXML = new StringBuffer();
    requestXML.append(getProcessWorkOrderSOAPXML());   
    // get list of user     
    out.println(requestXML.toString()); 
    out.close();
    out.flush();
    System.out.println("XML Request POSTed to " + xmlServerURL + "\n");
    System.out.println(requestXML.toString() + "\n"); 
    //Thread.sleep(60000);  
    // read response

    BufferedReader in = new BufferedReader(new InputStreamReader( 
            httpsURLConnection.getInputStream()));
    String line;
    String respXML = "";
    while ((line = in.readLine()) != null) {
        respXML += line;
    }
    in.close();

    // output response
    respXML = URLDecoder.decode(respXML, "UTF-8"); 
    System.out.println("\nXML Response\n");
    System.out.println(respXML);
}

Plein stacktrace:

Exception in thread "main" javax.net.ssl.SSLHandshakeException: Remote Host closed connection during handshake
       at Sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.Java:946)
       at Sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.Java:1312)
       at Sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.Java:1339)
       at Sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.Java:1323)
       at Sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.Java:563)
       at Sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.Java:185)
       at Sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.Java:1091)
       at Sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.Java:250)
       at com.labcorp.efone.vendor.TestATTConnectivity.main(TestATTConnectivity.Java:43)
Caused by: Java.io.EOFException: SSL peer shut down incorrectly
       at Sun.security.ssl.InputRecord.read(InputRecord.Java:482)
       at Sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.Java:927)
       ... 8 more

En fait, il existe deux scénarios. Lorsque je travaille en tant que programme Java autonome, je reçois l'exception ci-dessus. Mais lorsque j'essaie d'exécuter sur le serveur d'applications weblogic, j'obtiens l'exception ci-dessous: aucun indice quelle pourrait être la raison?

Java.io.IOException: Connection closed, EOF detected
    at weblogic.socket.JSSEFilterImpl.handleUnwrapResults(JSSEFilterImpl.Java:637)
    at weblogic.socket.JSSEFilterImpl.unwrapAndHandleResults(JSSEFilterImpl.Java:515)
    at weblogic.socket.JSSEFilterImpl.doHandshake(JSSEFilterImpl.Java:96)
    at weblogic.socket.JSSEFilterImpl.doHandshake(JSSEFilterImpl.Java:75)
    at weblogic.socket.JSSEFilterImpl.write(JSSEFilterImpl.Java:448)
    at weblogic.socket.JSSESocket$JSSEOutputStream.write(JSSESocket.Java:93)
    at Java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.Java:82)
    at Java.io.BufferedOutputStream.flush(BufferedOutputStream.Java:140)
    at Java.io.FilterOutputStream.flush(FilterOutputStream.Java:140)
    at weblogic.net.http.HttpURLConnection.writeRequests(HttpURLConnection.Java:192)
    at weblogic.net.http.HttpURLConnection.getInputStream(HttpURLConnection.Java:433)
    at weblogic.net.http.SOAPHttpsURLConnection.getInputStream(SOAPHttpsURLConnection.Java:37)
    at com.labcorp.efone.service.impl.WorkOrderServiceImpl.processATTWorkOrder(ATTWorkOrderServiceImpl.Java:86)
    at com.labcorp.efone.bds.WorkOrderBusinessDelegateImpl.processATTWorkOrder(WorkOrderBusinessDelegateImpl.Java:59)
    at com.labcorp.efone.actions.ATTWorkOrderAction.efonePerformForward(ATTWorkOrderAction.Java:41)
    at com.labcorp.efone.actions.EfoneAction.efonePerformActionForward(EfoneAction.Java:149)
    at com.labcorp.efone.actions.EfoneAction.execute(EfoneAction.Java:225)
    at org.Apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.Java:484)
    at org.Apache.struts.action.RequestProcessor.process(RequestProcessor.Java:274)
    at org.Apache.struts.action.ActionServlet.process(ActionServlet.Java:1482)
    at org.Apache.struts.action.ActionServlet.doPost(ActionServlet.Java:525)
    at javax.servlet.http.HttpServlet.service(HttpServlet.Java:751)
    at javax.servlet.http.HttpServlet.service(HttpServlet.Java:844)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.Java:280)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.Java:254)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.Java:136)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.Java:341)
    at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.Java:25)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.Java:79)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:330)
    at com.labcorp.efone.security.EfoneAuthenticationFilter.doFilter(EfoneAuthenticationFilter.Java:115)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.Java:87)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.Java:192)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.Java:160)
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.Java:346)
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.Java:259)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.Java:79)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.Java:3367)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.Java:3333)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.Java:321)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.Java:120)
    at weblogic.servlet.provider.WlsSubjectHandle.run(WlsSubjectHandle.Java:57)
    at weblogic.servlet.internal.WebAppServletContext.doSecuredExecute(WebAppServletContext.Java:2220)
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.Java:2146)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.Java:2124)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.Java:1564)
    at weblogic.servlet.provider.ContainerSupportProviderImpl$WlsRequestExecutor.run(ContainerSupportProviderImpl.Java:254)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.Java:295)
    at weblogic.work.ExecuteThread.run(ExecuteThread.Java:254)
Exception: Java.io.IOException: Connection closed, EOF detected
55
user3216923

Java 7 utilise par défaut TLS 1.0, ce qui peut entraîner cette erreur lorsque ce protocole n'est pas accepté. J'ai rencontré ce problème avec une application Tomcat et un serveur qui n'accepterait plus les connexions TLS 1.0. J'ai ajouté

-Dhttps.protocols=TLSv1.1,TLSv1.2

aux options de Java et qui l'a corrigé. (Tomcat exécutait Java 7.)

57
Erica Kane

J'ai rencontré le même problème, je l'ai résolu en ajoutant:

System.setProperty("https.protocols", "TLSv1,TLSv1.1,TLSv1.2");

before openConnection méthode.

20
Kamal SABBAR

Pas encore une réponse, mais trop pour un commentaire. Ce n'est clairement pas un problème de certificat de serveur; les symptômes sont très différents. À partir du POV de votre système, le serveur semble se fermer lors de la prise de contact. Il y a deux possibilités:

Le serveur est en train de se fermer, ce qui constitue une violation du protocole SSL/TLS, bien que mineur; il existe plusieurs raisons pour lesquelles un serveur peut échouer avec vous, mais il doit d'abord envoyer une alerte fatale, ce que votre JSSE ou son équivalent weblogic doit indiquer. Dans ce cas, il est possible que des informations utiles figurent dans le journal du serveur, si vous êtes capable (et autorisé) de communiquer avec un ou plusieurs administrateurs de serveur bien informés. Vous pouvez également essayer de placer un moniteur réseau sur votre ordinateur client ou un moniteur suffisamment proche pour voir tout votre trafic. Personnellement, j'aime www.wireshark.org. Mais cela montre généralement que la fermeture intervient immédiatement après ClientHello, ce qui ne la réduit pas beaucoup. Vous ne dites pas si vous êtes censé avoir configuré un "cert client" (en réalité une clé & cert, sous la forme d'une Java privateKeyEntry) pour ce serveur; si cela est requis par le serveur et qu'il n'est pas correct, certains serveurs peuvent / perçoivent cela comme une attaque et violent sciemment le protocole en se fermant bien qu'officiellement, ils devraient envoyer une alerte.

Ou bien, un boîtier du réseau, le plus souvent un pare-feu ou un proxy prétendument transparent, décide de ne pas aimer votre connexion et d’imposer une fermeture forcée. Le proxy que vous utilisez est un suspect évident; lorsque vous dites que le "même code" fonctionne pour les autres hôtes, confirmez si vous voulez dire par le biais de même proxy (pas seulement un proxy) et en utilisant HTTPS (pas de HTTP clair). Si ce n'est pas le cas, essayez de tester d'autres hôtes avec HTTPS via le proxy (vous n'avez pas besoin d'envoyer une demande complète SOAP, mais simplement un GET/si suffisant). Si vous le pouvez, essayez de vous connecter sans le proxy, ou éventuellement avec un proxy différent, et en connectant HTTP (et non S) via le proxy à l'hôte (si les deux prennent en charge la suppression) et voyez si cela fonctionne.

Si la publication de l'hôte réel ne vous dérange pas (mais certainement pas les informations d'authentification), d'autres peuvent l'essayer. Ou vous pouvez aller sur www.ssllabs.com et leur demander de tester le serveur (sans publier les résultats); cela va essayer plusieurs variantes courantes de la connexion SSL/TLS et signaler toutes les erreurs qu'il voit, ainsi que les faiblesses de sécurité.

16
dave_thompson_085

Je pense que vos certificats vous manquent.

Vous pouvez essayer de les générer en utilisant l’application InstallCerts. Ici vous pouvez voir comment l'utiliser: https://github.com/escline/InstallCert

Une fois que vous avez obtenu votre certificat, vous devez le placer dans votre répertoire de sécurité dans votre répertoire personnel jdk, par exemple:

C:\Program Files\Java\jdk1.6.0_45\jre\lib\security

Laissez-moi savoir si cela fonctionne.

7
Federico Piazza

J'ai rencontré un problème similaire avec le serveur d'applications Glassfish et Oracle JDK/JRE, mais pas dans Open JDK/JRE.

Lors de la connexion à un domaine SSL, je rencontrais toujours:

javax.net.ssl.SSLHandshakeException: Remote Host closed connection during handshake
...
Caused by: Java.io.EOFException: SSL peer shut down incorrectly

Pour moi, la solution consistait à installer fichiers de stratégie juridictionnelle de force illimitée JCE (Java Cryptography Extension)} car le serveur ne comprenait que les certificats non inclus dans le JDK Oracle par défaut, seul OpenJDK les inclut. tout installer a fonctionné comme un charme.


JCE 7: http://www.Oracle.com/technetwork/Java/javase/downloads/jce-7-download-432124.html

JCE 8: http://www.Oracle.com/technetwork/Java/javase/downloads/jce8-download-2133166.html

6
McIntosh

Une première étape pour diagnostiquer le problème consiste à démarrer le client - et si vous exécutez le serveur vous-même, une instance de test privée du serveur - en démarrant Java avec l'option VM:

-Djavax.net.debug=all

Voir aussi https://blogs.Oracle.com/Java-platform-group/entry/diagnosing_tls_ssl_and_https

6
Henno Vermeulen

J'ai rencontré un problème similaire et j'ai découvert que je me trouvais dans le mauvais port. Après avoir réparé le port, les choses ont bien fonctionné.

2
user3225313

Dans mon cas, j'ai eu ce problème parce que j'avais donné au serveur un certificat inexistant, à cause d'une faute de frappe dans le fichier de configuration. Au lieu de lancer une exception, le serveur a procédé comme d'habitude et a envoyé un certificat vide au client. Il peut donc être intéressant de vérifier que le serveur fournit la réponse correcte.

J'ai rencontré cette erreur lors de l'utilisation du client Jersey pour me connecter à un serveur. J'ai résolu le problème en déboguant la bibliothèque et en constatant qu'elle recevait effectivement un EOF au moment où elle tentait de lire. J'ai également essayé de me connecter à l'aide d'un navigateur Web et d'obtenir les mêmes résultats.

Il suffit d'écrire ceci ici au cas où cela aiderait quelqu'un.

1
Parisbre56

Je lance mon application avec Java 8 et Java 8 a apporté un certificat de sécurité sur son magasin de données de confiance. Ensuite, je suis passé à Java 7 et ajouté ce qui suit dans les options VM:

-Djavax.net.ssl.trustStore=C:\<....>\Java8\jre\lib\security\cacerts

J'ai simplement indiqué l'endroit où se trouve un certificat.

1
Rare Case

Merci à tous d'avoir partagé vos réponses et vos exemples. Le même programme autonome a fonctionné pour moi avec de petits changements et l’ajout des lignes de code ci-dessous.

Dans ce cas, le fichier de magasin de clés a été fourni par le fournisseur de services Web.

// Small changes during connection initiation.. 

// Please add this static block 

      static {

        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()

            {   @Override

        public boolean verify(String hostname, SSLSession arg1) {

        // TODO Auto-generated method stub

                if (hostname.equals("X.X.X.X")) {

                    System.out.println("Return TRUE"+hostname);

                    return true;

                }

                System.out.println("Return FALSE");

                return false;

              }
               });
         }


String xmlServerURL = "https://X.X.X.X:8080/services/EndpointPort";


URL urlXMLServer = new URL(null,xmlServerURL,new Sun.net.www.protocol.https.Handler());


HttpsURLConnection httpsURLConnection = (HttpsURLConnection) urlXMLServer               .openConnection();

// Below extra lines are added to the same program

//Keystore file 

 System.setProperty("javax.net.ssl.keyStore", "Drive:/FullPath/keystorefile.store");

 System.setProperty("javax.net.ssl.keyStorePassword", "Password"); // Password given by vendor

//TrustStore file

System.setProperty("javax.net.ssl.trustStore"Drive:/FullPath/keystorefile.store");

System.setProperty("javax.net.ssl.trustStorePassword", "Password");
1
Laxman

J'ai rencontré ce problème avec Java 1.6. Courir sous Java 1.7 corrige mon interprétation particulière du problème. Je pense que la cause sous-jacente était que le serveur auquel je me connectais devait avoir besoin d'un cryptage plus puissant que celui disponible sous 1.6.

1
matt forsythe

Vous pouvez écrire ceci ci-dessous dans le code de votre programme Java actuel

System.setProperty ("https.protocols", "TLSv1.1");

ou 

System.setProperty ("http.proxyHost", "proxy.com"); System.setProperty ("http.proxyPort", "911");

1
Srinivas Thouti

J'utilisais la p12 que j'avais exportée avec Keychain sur mon MacBook, mais cela ne fonctionnait pas avec le code de mon serveur Java-apns. Ce que je devais faire était de créer une nouvelle clé p12 comme indiqué par ici , en utilisant mes clés pem déjà générées:

openssl pkcs12 -export -in your_app.pem -inkey your_key.pem -out your_app_key.p12

Puis mis à jour le chemin d'accès à ce nouveau fichier p12 et tout fonctionnait parfaitement.

0
Cyberdelphos

J'ai eu la même erreur, mais dans mon cas, cela était dû au mode DEBUG dans Intellij IDE. Le débogage a ralenti la bibliothèque puis le serveur a mis fin à la communication lors de la phase de prise de contact. La norme "RUN" a parfaitement fonctionné.

0
Bechyňák Petr

J'ai fait face au même problème une fois. Je pense que c'est à cause de l'URL 

String xmlServerURL = " https://example.com/soap/WsRouter ";

Vérifiez si c'est un bon ou pas ??

javax.net.ssl.SSLHandshakeException est dû au fait que le serveur n'a pas pu se connecter à l'URL spécifiée pour la raison suivante

  • Soit l'identité du site n'est pas vérifiée.
  • Le certificat du serveur ne correspond pas à l'URL.
  • Ou, le certificat du serveur n'est pas approuvé.
0
Manjunath Adoor

Comment tu le résoudrais en allant à 

  1. Réglages

  2. Recherchez "Réseau"

  3. Choisissez "Utiliser les paramètres généraux du proxy IDEA comme sous-version par défaut" 

0
W.Shawn