35

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) 
9
  • 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.CommentedApr 1, 2011 at 0: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
    CommentedApr 1, 2011 at 1: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
    CommentedApr 1, 2011 at 1:35
  • 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.CommentedApr 1, 2011 at 1: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
    CommentedApr 1, 2011 at 17:44

2 Answers 2

64

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 
3
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
  • 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.
    – CommunityBot
    CommentedJul 12, 2022 at 4:01

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.