String url1 = "foo1.blabla.com";
String url2 = "foo2_bar.blabla.com";
URLConnection urlConnection = new URL(url1).openConnection();
urlConnection.setDoInput(true);
//Fails
InputStream in = urlConnection.getInputStream();
We were able to connect url1 without problems, but they recently changed their url to url2 and claim that they only changed their url and nothing else. But after the modification I got the following exceptions:
java.net.SocketException: Connection reset at java.net.SocketInputStream.read(SocketInputStream.java:210) at java.net.SocketInputStream.read(SocketInputStream.java:141) at sun.security.ssl.InputRecord.readFully(InputRecord.java:465) at sun.security.ssl.InputRecord.read(InputRecord.java:503) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:975) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379) at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
I tried Java 1.8.181, 1.8.191.
I tried using customhostnameverifier such as
class CustomHostNameVerifier implements HostnameVerifier {
public CustomHostNameVerifier() {
}
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
}
Both url1 and url2 have same certificate information, I also added their .cer into keystore using keytool.
There is not firewall or antivirus issue becasue on same computer I can connect to url2 with postman. I added same headers like postman to my java code.
I checked following so pages:
java.net.SocketException: Connection reset With HTTPConnection
What's causing my java.net.SocketException: Connection reset?
java.net.SocketException: Connection reset
connection reset on HttpsUrlConnection with valid URL
and see the following differences:
for url1 (working fine)
SendHTTPTest.f9() connection opened Allow unsafe renegotiation: false Allow legacy hello messages: true Is initial handshake: true Is secure renegotiation: false main, the previous server name in SNI (type=host_name (0), value=foo1.blabla.com) was replaced with (type=host_name (0), value=foo1.blabla.com) Extension extended_master_secret Extension server_name, server_name: [type=host_name (0), value=foo1.blabla.com] *** main, WRITE: TLSv1.2 Handshake, length = 226 main, READ: TLSv1.2 Handshake, length = 2303 *** ServerHello, TLSv1.2
for url2 (connection reset problem)
SendHTTPTest.f9() connection opened main, "foo2_bar.blabla.com" is not a legal HostName for server name indication Allow unsafe renegotiation: false Allow legacy hello messages: true Is initial handshake: true Is secure renegotiation: false main, "foo2_bar.blabla.com" is not a legal HostName for server name indication main, WRITE: TLSv1.2 Handshake, length = 193 main, handling exception: java.net.SocketException: Connection reset main, SEND TLSv1.2 ALERT: fatal, description = unexpected_message main, WRITE: TLSv1.2 Alert, length = 2 main, Exception sending alert: java.net.SocketException: Connection reset by peer: socket write error main, called closeSocket() java.net.SocketException: Connection reset
Probably the message causes main, "foo2_bar.blabla.com" is not a legal HostName for server name indication the problem, it is SNI related? Underscore in url2 may cause problem?
(From comments for resolution, and search)
Many things can cause reset on SSL/TLS handshake, depending on the server, but nowadays a common one is missing Server Name Indication (SNI).
Aside from bugs in some older versions, Java (JSSE) fails to send SNI in several cases:
hostname is an IP address (v4 or v6)
hostname contains no dot, or has dot at end (i.e. doesn't 'look like' a DNS name)
hostname contains ASCII characters other than letters, digits, and hyphen (in the positions allowed by DNS and IDN) and dot (in the positions allowed by DNS); this restriction is apparently based on RFC952 as referenced in STD3=RFC1123. (NonASCII characters -- Unicode U+0080 and up -- are converted following IDN rules to punycode, which by design satisfies the restrictions.)
In this case the problem was the third point; the hostname contained an ASCII underscore.