34

I am attempting to connect to an HTTPS endpoint in Java. Every method I have tried (more details below) ends up generating this stack trace:

java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:168)
at com.sun.net.ssl.internal.ssl.InputRecord.readFully(InputRecord.java:293)
at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:331)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:798)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:753)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75)

I have tried:

  • Connecting with the javax SOAP libs and a new URL("https://...")
  • Connecting with new URL("https://...").openConnection()
  • Creating an SSL connection by hand:

            Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
        SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
    
        SSLSocket socket = (SSLSocket) factory.createSocket("...", 443);
    
        Writer out = new OutputStreamWriter(socket.getOutputStream());
        // https requires the full URL in the GET line
        //
        out.write("GET / HTTP/1.0\r\n");
        out.write("\r\n");
        out.flush();
    
        // read response
        BufferedReader in = new BufferedReader(
                    new InputStreamReader(socket.getInputStream()));
        int c;
        while ((c = in.read()) != -1) {
            System.out.write(c);
        }
    
        out.close();
        in.close();
        socket.close();
    

A few more details:

  • Every method I have tried has worked against other SSL servers, it's this particular server (I am not at liberty to discuss what server, it's a business partner)
  • I can connect to this server both with a web browser, and with a faked up SOAP request with curl; This is something Java-specific.

So, it seems pretty clear that there is some disagreement between Java and the HTTPS server over how the handshake should go down, which probably means the server has some strange SSL configuration. However, I don't have direct access to the server, and the people who do are halfway around the world, so communication is a little strained due to very different timezones.

If my assumptions there are correct, what possible SSL problems could there be? What might cause something like this? Where can I ask the people in control of the server to look for issues? When I do the request with curl, I get back these server configuration headers:

Server: Apache/2.2.9 (Debian) mod_jk/1.2.26 PHP/5.2.6-1+lenny10 with Suhosin-Patch mod_ssl/2.2.9 OpenSSL/0.9.8g mod_perl/2.0.4 Perl/v5.10.0
X-Powered-By: PHP/5.2.6-1+lenny10
X-SOAP-Server: NuSOAP/0.7.3 (1.114)
huelbois
  • 6,762
  • 1
  • 19
  • 21
roguenet
  • 1,273
  • 1
  • 11
  • 18
  • That exception trace doesn't show where in your code the problem is occurring. Maybe the SSL connection has been successfully made and the problem is in your HTTP. – President James K. Polk Apr 01 '11 at 00:48
  • Where it occurs in my code varies on the method I use. It always happens either on the out.flush() or on starting to read the connection. The part I included is always the same though - the problem is in the handshake at some point. – roguenet Apr 01 '11 at 01:35
  • Update: it is probably an SSL version problem. I've discovered that the server only supports SSLv3, and Java will start at v2, and attempt to negotiate upwards, but not all servers support that type of negotiation. I'll post again when I know that this was the problem for sure. – roguenet Apr 01 '11 at 01:35
  • Yup, that was the issue. Case closed. – roguenet Apr 01 '11 at 01:56
  • 1
    @Nathan: You should answer your own question with the solution and then accept your answer. You won't get any points, but it will show up as an answered question to other people with the same problem, and might help somebody else. – Jim Garrison Apr 01 '11 at 01:59
  • 2
    Yeah, I answered it, but I can't accept my own answer for 48 hours. I'll do so when allowed. Thanks! – roguenet Apr 01 '11 at 17:44
  • I had the same problem with JDK6, and it was related to self signed certificate on HTTPS server side. Did you use self signed certificate? – Oleg Mikheev Oct 31 '13 at 05:20
  • I don't believe that server had self-signed certs, but this was a couple years ago and it was a partner's server, not my own so I don't remember for sure. – roguenet Oct 31 '13 at 22:35
  • I faced this error when the website SSL requires SNI – firstpostcommenter Jan 29 '21 at 03:05

2 Answers2

65

It is an SSL version problem. The server only supports SSLv3, and Java will start at v2, and attempt to negotiate upwards, but not all servers support that type of negotiation.

Forcing java to use SSLv3 only is the only solution I'm aware of.

Edit, there are two ways to do this that I'm aware of:

  • If you are creating the socket by hand, you can set the enabled protocols

    socket.setEnabledProtocols(new String[] { "SSLv3" });
    
  • If you are using a higher level library, you probably need to set all SSL requests to use v3 only, which is accomplished with the "https.protocols" system property:

    java -Dhttps.protocols=SSLv3
    
roguenet
  • 1,273
  • 1
  • 11
  • 18
0

Maybe also try setting the HTTP version to 1.1 instead of 1.0, as there's some real advantages to the newer standard.

  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 12 '22 at 04:01