Меню

Remote host terminated the handshake ошибка

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/Lokeshkeysmaven.jks" 
    -Djavax.net.ssl.keyStorePassword="test" 
    -Djavax.net.ssl.trustStore="C:/Users/Lokeshkeysmaven.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 !!

javax.net.ssl.SSLHandshakeException: Remote host terminated the handshake
	at java.base/sun.security.ssl.SSLSocketImpl.handleEOF(SSLSocketImpl.java:1616)
	at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1434)
	at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1336)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:450)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:421)
	at org.apache.http.conn.ssl.SSLConnectionSocketFactory.createLayeredSocket(SSLConnectionSocketFactory.java:436)
	at org.apache.http.conn.ssl.SSLConnectionSocketFactory.connectSocket(SSLConnectionSocketFactory.java:384)
	at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:142)
	at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:376)
	at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
	at com.tabnine.logging.TabnineLogDispatcher$dispatchLog$1.run(TabnineLogDispatcher.kt:40)
	at com.intellij.openapi.application.impl.ApplicationImpl$1.run(ApplicationImpl.java:263)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:668)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:665)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1.run(Executors.java:665)
	at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
	at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:483)
	at java.base/sun.security.ssl.SSLSocketInputRecord.readHeader(SSLSocketInputRecord.java:472)
	at java.base/sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:160)
	at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:111)
	at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1426)
	... 26 more

Will |
Last updated: May 20, 2020 09:59AM UTC

Hannah, PortSwigger Agent |
Last updated: May 20, 2020 01:41PM UTC

Will |
Last updated: May 21, 2020 05:01AM UTC

Hannah, PortSwigger Agent |
Last updated: May 21, 2020 07:18AM UTC

Will |
Last updated: May 21, 2020 07:51AM UTC

Hannah, PortSwigger Agent |
Last updated: May 21, 2020 08:18AM UTC

Will |
Last updated: May 21, 2020 10:31AM UTC

Hannah, PortSwigger Agent |
Last updated: May 22, 2020 07:47AM UTC

Manu |
Last updated: Sep 30, 2021 05:54PM UTC

Manu |
Last updated: Sep 30, 2021 05:54PM UTC

Hannah, PortSwigger Agent |
Last updated: Oct 04, 2021 03:04PM UTC

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Remote host closed connection during handshake ошибка
  • Redmond rmc m45011 ошибка e2