javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake during web service communicaiton
Asked Answered
E

21

105

I am getting javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake exception when I try to do HTTPS Post of a web service through internet. But same code works for other internet hosted web services. I tried many things, nothing is helping me. I posted my sample code here. Can anyone please help me to resolve this problem?

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

Full 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

Actually, there are two scenarios here. When I work as a standalone Java program I am getting the above exception. But when I try to execute in weblogic application server, I am getting the below exception: Any clue what could be the reason?

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
Espagnole answered 20/1, 2014 at 22:52 Comment(5)
Another of the many possible reasons can be broken or very low quality connectionPalaeolithic
What happens if you use another program to test your web-service like curl or soap-ui? I have similar problem and it works with curl but not from my Java runtime (servicemix). I suspect it could also be the client 'cacert' not containing the server's certificate.Ferial
In case anyone has arrived on this page through gradle, which is not what the OP is asking, make sure you set JAVA_HOME to Java 8 or later.Snippy
duplicated with #28909335Demott
@LIUYUE How can a question asked in January 2014 be a duplicate of a question asked in March 2015? Maybe the answer is the same, but that does not mean they are duplicatesEntertainment
H
88

Java 7 defaults to TLS 1.0, which can cause this error when that protocol is not accepted. I ran into this problem with a Tomcat application and a server that would not accept TLS 1.0 connections any longer. I added

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

to the Java options and that fixed it. (Tomcat was running Java 7.)

Hardcastle answered 20/1, 2016 at 3:55 Comment(9)
Where should I add that line of code? inside which file? Could you tell directory path?Minoru
It's not code, it's part of the Java options that are set when you call the Java executable. The exact answer will depend on your operating system and program. For Tomcat on Windows as in this example, running Tomcat7w will get you started, then modify Java options. In other cases you add the options to your initialization file, or for java.exe command-line, adding it there. I would definitely recommend researching Java options rather than blindly adding this in if you are not familiar with them. A good place is start is docs.oracle.com/javase/7/docs/technotes/tools/windows/java.html .Hardcastle
@EricaKane - Its nice to have an answer. But, how do we debug this issue and find out what the cause is ? (i.e. how do we arrive at your solution ?)Toscano
If you are dealing with a public-facing website, you can use SSL Labs or another tool to see which protocol they will accept. If they don't accept TLS 1.0 anymore (and frankly, most don't) and you are using Java 7, you will need to implement this. As to how I specifically debugged this initially, I no longer remember.Hardcastle
This seems to be still true for Java 8 and Java Web Start of that one. Just added <property name="https.protocols" value="TLSv1.1,TLSv1.2"/> to a JNLP file to make Web Start operational again...Carper
I am getting javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure? Any suggestions? I have tried adding the property, but no luckShrift
@EricaKane have you set 2 version of TLS at the same time?Regression
this helped me with my issueWira
@Regression the answer given is a list of available protocols to try to connect.Hardcastle
T
48

I faced the same problem and solved it by adding:

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

before openConnection method.

Talcahuano answered 30/9, 2016 at 10:3 Comment(1)
I would prefer this kind of solutions over the top-voted one :)Albina
I
26

Not an answer yet, but too much for a comment. This is clearly not a server cert problem; the symptoms of that are quite different. From your system's POV, the server appears to be closing during the handshake. There are two possibilities:

The server really is closing, which is a SSL/TLS protocol violation though a fairly minor one; there are quite a few reasons a server might fail to handshake with you but it should send a fatal alert first, which your JSSE or the weblogic equivalent should indicate. In this case there may well be some useful information in the server log, if you are able (and permitted) to communicate with knowledgeable server admin(s). Or you can try putting a network monitor on your client machine, or one close enough it sees all your traffic; personally I like www.wireshark.org. But this usually shows only that the close came immediately after the ClientHello, which doesn't narrow it down much. You don't say if you are supposed to and have configured a "client cert" (actually key&cert, in the form of a Java privateKeyEntry) for this server; if that is required by the server and not correct, some servers may perceive that as an attack and knowingly violate protocol by closing even though officially they should send an alert.

Or, some middlebox in the network, most often a firewall or purportedly-transparent proxy, is deciding it doesn't like your connection and forcing a close. The Proxy you use is an obvious suspect; when you say the "same code" works to other hosts, confirm if you mean through the same proxy (not just a proxy) and using HTTPS (not clear HTTP). If that isn't so, try testing to other hosts with HTTPS through the proxy (you needn't send a full SOAP request, just a GET / if enough). If you can, try connecting without the proxy, or possibly a different proxy, and connecting HTTP (not S) through the proxy to the host (if both support clear) and see if those work.

If you don't mind publishing the actual host (but definitely not any authentication credentials) others can try it. Or you can go to www.ssllabs.com and request they test the server (without publishing the results); this will try several common variations on SSL/TLS connection and report any errors it sees, as well as any security weaknesses.

Illegality answered 25/3, 2014 at 8:29 Comment(0)
O
16

A first step to diagnose the issue is by starting the client - and if you are running the server yourself, a private test instance of the server - by starting Java with the VM option:

-Djavax.net.debug=all

See also https://blogs.oracle.com/java-platform-group/entry/diagnosing_tls_ssl_and_https

Ostracism answered 24/3, 2017 at 21:9 Comment(0)
M
8

I think you are missing your certificates.

You can try generating them by using InstallCerts app. Here you can see how to use it: https://github.com/escline/InstallCert

Once you get your certificate, you need to put it under your security directory within your jdk home, for example:

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

Let me know if it works.

Mandle answered 5/2, 2014 at 22:15 Comment(2)
both links are downLawley
@Lawley i've updated the links... btw, my answer doesn't attempt to explain how to generate certificates but where to put them. I added that link as a context information in case OP wants to dig deeper in the cert generation.Mandle
D
8

I encountered a similar problem with glassfish application server and Oracle JDK/JRE but not in Open JDK/JRE.

When connecting to a SSL domain I always ran into:

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

The solution for me was to install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files because the server only understood certificates that are not included in Oracle JDK by default, only OpenJDK includes them. After installing everything worked like 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

Darryl answered 27/10, 2015 at 13:41 Comment(0)
W
4

I ran into a similar issue and found I was hitting the wrong port. After fixing the port things worked great.

Wooldridge answered 12/5, 2014 at 16:55 Comment(0)
P
4

In my case, I got this problem because I had given the server a non-existent certificate, due to a typo in the config file. Instead of throwing an exception, the server proceeded like normal and sent an empty certificate to the client. So it might be worth checking to make sure that the server is providing the correct response.

I experienced this error while using the Jersey Client to connect to a server. The way I resolved it was by debugging the library and seeing that it actually did receive an EOF the moment it tried to read. I also tried connecting using a web browser and got the same results.

Just writing this here in case it ends up helping anyone.

Pagas answered 20/1, 2016 at 12:34 Comment(0)
E
3

You May Write this below code insdie your current java programme

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

or

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

System.setProperty("http.proxyPort", "911");

Examinant answered 9/11, 2017 at 7:23 Comment(0)
T
1

Thanks to all for sharing your answers and examples. The same standalone program worked for me by small changes and adding the lines of code below.

In this case, keystore file was given by webservice provider.

// 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");
Tractor answered 4/9, 2014 at 4:41 Comment(0)
L
1

I encountered this problem with Java 1.6. Running under Java 1.7 fixed my particular rendition of the problem. I think the underlying cause was that the server I was connecting to must have required stronger encryption than was available under 1.6.

Lublin answered 28/7, 2015 at 21:21 Comment(0)
M
1

I had the same error, but in my case it was caused by the DEBUG mode in Intellij IDE. The debug slowed down the library and then server ended communication at handshake phase. The standard "RUN" worked perfectly.

Mauritamauritania answered 24/11, 2015 at 12:38 Comment(0)
M
1

I run my application with Java 8 and Java 8 brought security certificate onto its trust store. Then I switched to Java 7 and added the following into VM options:

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

Simply I pointed to the location where a certificate is.

Metalepsis answered 30/1, 2018 at 19:32 Comment(0)
I
0

I was using the p12 which I exported with Keychain in my MacBook, however, it didn't work on my java-apns server code. What I had to do was to create a new p12 key as stated here, using my already generated pem keys:

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

Then updated the path to that new p12 file and everything worked perfectly.

Ionopause answered 14/8, 2015 at 17:46 Comment(0)
H
0

How you would solve it is by going to

  1. Settings

  2. Search"Network"

  3. Choose "Use IDEA general proxy settings as default Subversion"

Heinrick answered 9/4, 2018 at 2:54 Comment(0)
O
0

With base at TLSv1.2 ALERT: fatal, handshake_failure I obtained after debug with this thread previos answer

-Djavax.net.debug=all

I went to https://www.ssllabs.com/and observed that the web server required a SSLv3 connection deprecate at june 2015, and deprecated at JDKu31 Release notes

ssllabs results

I edited the ${java_home}/jre/lib/security/java.security at the line

jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, DH keySize < 1024,
EC keySize < 224, 3DES_EDE_CBC, anon, NULL

to

jdk.tls.disabledAlgorithms= RC4, DES, MD5withRSA, DH keySize < 1024,
EC keySize < 224, 3DES_EDE_CBC, anon, NULL

As a final step I got this error

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target [javax.net.ssl.SSLHandshakeException]

I fixed this intalling the cert with the java keytool, following this answer PKIX path building failed” and “unable to find valid certification path to requested target”

Orleans answered 23/6, 2020 at 3:49 Comment(0)
L
0

I get this error when specifying a https url and in the same url explicitly specifying an http port (instead of an https port). Removing the explicit port :8080 solved the issue for me.

Lightfoot answered 23/3, 2021 at 9:31 Comment(0)
P
-1

Adding certificates to Java\jdk\jre\lib\security folder worked for me. If you are using Chrome click on the green bulb [https://support.google.com/chrome/answer/95617?p=ui_security_indicator&rd=1] and save the certificate in security folder.

Presbyterate answered 16/7, 2014 at 3:17 Comment(0)
R
-2

I faced the same issue once. I think its because of the URL

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

Check whether its a proper one or not ??

javax.net.ssl.SSLHandshakeException is because the server not able to connect to the specified URL because of following reason-

  • Either the identity of the website is not verified.
  • Server's certificate does not match the URL.
  • Or, Server's certificate is not trusted.
Royo answered 22/4, 2016 at 5:46 Comment(1)
This SSLHandshakeException isn't caused by any of those things.Redintegration
N
-2

As per https://kb.informatica.com/solution/23/Pages/69/570664.aspx adding this property works:

CryptoProtocolVersion=TLSv1.2
Nitty answered 17/3, 2020 at 7:47 Comment(1)
That applies specifically to the DataDirect JDBC Driver. Not mentioned in the question here.Redintegration
I
-7

This is what solve my problem.

If you are trying to use debugger make sure you breakpoint is not on URL or URLConnection just put your breakpoint on BufferReader or inside while loop.

If nothing works try using apache library http://hc.apache.org/index.html.

no SSL, no JDK update needed, no need to set properties even, just simple trick :)

Ingaingaberg answered 27/2, 2018 at 4:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.