Remote host closed connection during handshake azure

I am using Microsoft Reporting API to get Azure AD Logon Activity. When i request access token,I am getting SSL handshake exception sometime. Sometime working fine without an issue

Url to get access token : https://login.microsoftonline.com/test.onmicrooft.com/oauth2/token?api-version=1.0

Stacktrace

[10:03:48:293]|[12-23-2020]|[SYSERR]|[INFO]|[931]: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake|

[10:03:48:293]|[12-23-2020]|[SYSERR]|[INFO]|[931]: at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:992)|
[10:03:48:293]|[12-23-2020]|[SYSERR]|[INFO]|[931]: at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)|
[10:03:48:293]|[12-23-2020]|[SYSERR]|[INFO]|[931]: at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403)|
[10:03:48:293]|[12-23-2020]|[SYSERR]|[INFO]|[931]: at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387)|
[10:03:48:293]|[12-23-2020]|[SYSERR]|[INFO]|[931]: at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:563)|
[10:03:48:293]|[12-23-2020]|[SYSERR]|[INFO]|[931]: at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)|
[10:03:48:293]|[12-23-2020]|[SYSERR]|[INFO]|[931]: at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1282)|
[10:03:48:293]|[12-23-2020]|[SYSERR]|[INFO]|[931]: at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1257)|
[10:03:48:293]|[12-23-2020]|[SYSERR]|[INFO]|[931]: at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:250)|
[10:03:48:293]|[12-23-2020]|[SYSERR]|[INFO]|[931]: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)|
[10:03:48:293]|[12-23-2020]|[SYSERR]|[INFO]|[931]: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)|
[10:03:48:293]|[12-23-2020]|[SYSERR]|[INFO]|[931]: at java.lang.Thread.run(Thread.java:745)|
[10:03:48:293]|[12-23-2020]|[SYSERR]|[INFO]|[931]: Caused by: java.io.EOFException: SSL peer shut down incorrectly|
[10:03:48:293]|[12-23-2020]|[SYSERR]|[INFO]|[931]: at sun.security.ssl.InputRecord.read(InputRecord.java:505)|
[10:03:48:293]|[12-23-2020]|[SYSERR]|[INFO]|[931]: at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)|
[10:03:48:293]|[12-23-2020]|[SYSERR]|[INFO]|[931]: ... 14 more|

Remote host closed connection during handshake azure

  • Remove From My Forums

  • Question

  • Hi,

    Are there any issues with Azure Blob Storage in Australia East region?

    One of our clients has lost the ability to connect to the storage account over the weekend? The issue is related to TLS protocol version.

    Azure Status page showing everything ok. 


    Henryk

Answers

    • Proposed as answer by Adam Smith (Azure) Tuesday, January 30, 2018 4:42 PM
    • Marked as answer by HenrykA Thursday, February 1, 2018 9:42 AM

All replies

  • As far as we know, there has been no changes on their end.

    They first lost connectivity on their CERT system around Friday evening and the same thing happened on PROD on Monday morning.


    Henryk

    • Proposed as answer by Adam Smith (Azure) Tuesday, January 30, 2018 4:42 PM
    • Marked as answer by HenrykA Thursday, February 1, 2018 9:42 AM

SSLHandshakeException appear in logs when there is some error occur while validating the certificate installed in client machine with certificate on server machine. In this post, we will learn about fixing this if you are using Apache HttpClient library to create HttpClient to connect to SSL/TLS secured URLs.

The exception logs will look like this.

Caused by: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:980)
	at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1363)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1391)
	at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1375)
	at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:275)
	at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:254)
	at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:117)
	at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:314)
	at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:363)
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:219)
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195)
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86)
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:186)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
	at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:88)
	at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:46)
	at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:49)
	at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:509)
	... 61 more
Caused by: java.io.EOFException: SSL peer shut down incorrectly
	at sun.security.ssl.InputRecord.read(InputRecord.java:505)
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:961)
	... 80 more

I have already posted code fix to bypass SSL matching in earlier post.

Unfortunately, that fix works in TLS and TLS 1.1 protocols. It doesn’t work in TLS 1.2 protocol. So ultimately, you need to fix the certificate issue anyway. There is ‘no code only’ fix for this.

Now there are two ways, you can utilize the imported certificate from server. Either add certificate to the JDK cacerts store; or pass certificate information in JVM aruguments.

1) Import certificate to JDK cacert store

  1. Import the certificate from server.
  2. Use given command to add the certificate to JDK store. (Remove new line characters).
    keytool -import 
    	-noprompt 
    	-trustcacerts 
    	-alias MAVEN-ROOT 
    	-file C:/Users/Lokesh/keys/cert/maven.cer 
    	-keystore "C:/Program Files (x86)/Java/jdk8/jre/lib/security/cacerts" 
    	-storepass changeit
    

Now create HTTP client as given:

public HttpClient createTlsV2HttpClient() throws KeyManagementException, 
				UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException {

      SSLContext sslContext = SSLContext.getInstance("TLSv1.2");

      SSLConnectionSocketFactory f = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1.2" }, null,
                   						SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

      Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                   		.register("http", PlainConnectionSocketFactory.getSocketFactory())
                   		.register("https", f)
                   		.build();

      PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);

      CloseableHttpClient client = HttpClients
      					.custom()
      					.setSSLSocketFactory(f)
                   		.setConnectionManager(cm)
                   		.build();
      return client;
}

Notice the code : SSLContext.getInstance("TLSv1.2"). This code picks up the certificates added to JDK cacert store. So make a note of it.

2) Pass certificate information in JVM aruguments

  1. Import the certicate from server.
  2. Add JVM arguments while starting the server. Change the parameter values as per your application.
    -Djavax.net.ssl.keyStore="C:/Users/Lokesh\keys\maven.jks" 
    -Djavax.net.ssl.keyStorePassword="test" 
    -Djavax.net.ssl.trustStore="C:/Users/Lokesh\keys\maven.jks" 
    -Djavax.net.ssl.trustStorePassword="test" 
    

Now create HTTP client as given:

public HttpClient createTlsV2HttpClient() throws KeyManagementException, 
				UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException {

      SSLContext sslContext = SSLContexts.createSystemDefault();

      SSLConnectionSocketFactory f = new SSLConnectionSocketFactory(sslContext, new String[] { "TLSv1.2" }, null,
                   						SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

      Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                   		.register("http", PlainConnectionSocketFactory.getSocketFactory())
                   		.register("https", f)
                   		.build();

      PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(socketFactoryRegistry);

      CloseableHttpClient client = HttpClients
      					.custom()
      					.setSSLSocketFactory(f)
                   		.setConnectionManager(cm)
                   		.build();
      return client;
}

Notice the code : SSLContext.createSystemDefault(). This code picks up the certificates passed as JVM arguments. Again, make a note of it.

Summary

  1. Use SSLContext.getInstance("TLSv1.2") when certificate is added to JDK cacert store.
  2. Use SSLContext.createSystemDefault() when SSL info is passed as JVM argument.

Drop me your questions in comments section.

Happy Learning !!

Join 8000+ Awesome Developers, Like YOU!

What is remote host closed connection during handshake?

[SOLVED] TLS 1.2 – SSLHandshakeException: Remote host closed connection during handshake. SSLHandshakeException appear in logs when there is some error occur while validating the certificate installed in client machine with certificate on server machine.

How do I fix SSLHandshakeException?

SSLHandshakeException can be resolved 2 ways..
Incorporating SSL. Get the SSL (by asking the source system administrator, can also be downloaded by openssl command, or any browsers downloads the certificates) ... .
Ignoring SSL..