Remote host closed connection during handshake ошибка

Not an answer yet, but too much for a comment. This is clearly not a server cert problem; the symptoms of that are quite different. From your system’s POV, the server appears to be closing during the handshake. There are two possibilities:

The server really is closing, which is a SSL/TLS protocol violation though a fairly minor one; there are quite a few reasons a server might fail to handshake with you but it should send a fatal alert first, which your JSSE or the weblogic equivalent should indicate. In this case there may well be some useful information in the server log, if you are able (and permitted) to communicate with knowledgeable server admin(s). Or you can try putting a network monitor on your client machine, or one close enough it sees all your traffic; personally I like www.wireshark.org. But this usually shows only that the close came immediately after the ClientHello, which doesn’t narrow it down much. You don’t say if you are supposed to and have configured a «client cert» (actually key&cert, in the form of a Java privateKeyEntry) for this server; if that is required by the server and not correct, some servers may perceive that as an attack and knowingly violate protocol by closing even though officially they should send an alert.

Or, some middlebox in the network, most often a firewall or purportedly-transparent proxy, is deciding it doesn’t like your connection and forcing a close. The Proxy you use is an obvious suspect; when you say the «same code» works to other hosts, confirm if you mean through the same proxy (not just a proxy) and using HTTPS (not clear HTTP). If that isn’t so, try testing to other hosts with HTTPS through the proxy (you needn’t send a full SOAP request, just a GET / if enough). If you can, try connecting without the proxy, or possibly a different proxy, and connecting HTTP (not S) through the proxy to the host (if both support clear) and see if those work.

If you don’t mind publishing the actual host (but definitely not any authentication credentials) others can try it. Or you can go to www.ssllabs.com and request they test the server (without publishing the results); this will try several common variations on SSL/TLS connection and report any errors it sees, as well as any security weaknesses.

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

1. Problem

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)
...
...
Caused by: java.io.EOFException: SSL peer shut down incorrectly
  at sun.security.ssl.InputRecord.read(InputRecord.java:505)
...
...

I have already posted a code fix to bypass SSL matching in an 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 a ‘no code only’ fix for this.

2. Solution

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

2.1. Import certificate to JDK cacert Store

Import the certificate from the server.

Use the 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 the HttpClient 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.2. Pass certificate information in JVM aruguments

Import the certificate from the server.

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 an 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.

3. Conclusion

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

Drop me your questions in the comments section.

Happy Learning !!

  1. HowTo
  2. Java Howtos
  3. Javax.Net.SSL.SSLHandShakeException: …

Suraj P
Feb 15, 2023

  1. What Is javax.net.ssl.SSLHandshakeException
  2. How to Troubleshoot javax.net.ssl.SSLHandshakeException

Javax.Net.SSL.SSLHandShakeException: Remote Host Closed Connection During Handshake

In this article, we will learn about javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake in Java and some possible ways to troubleshoot this exception.

What Is javax.net.ssl.SSLHandshakeException

The javax.net.ssl.SSLHandshakeException is one of the common errors in a client-server application. Whenever we try to connect to a server or a website using SSL, we need to have the certificates, i.e., the public keys to validate the certificates sent by the website to which we are trying to connect.

In a nutshell, an exception is thrown when there is an error in the SSL/TLS handshake, specifically when the remote host (server) closes the connection during the handshake process.

There might be several reasons for this exception, such as:

  1. Incorrect SSL/TLS configurations on the client or server side.
  2. A certificate not trusted by the client (e.g., a self-signed certificate).
  3. A mismatch between the SSL/TLS versions supported by the client and server.
  4. Incorrect cipher suites being used.
  5. The remote host is blocking the SSL/TLS traffic.

How to Troubleshoot javax.net.ssl.SSLHandshakeException

To troubleshoot this issue, you can try the following.

  1. Verify that the SSL/TLS configurations on the client and server are correct.

    Verify SSL/TLS configurations

  2. Check that the client trusts the certificate being used.

  3. Ensure that the SSL/TLS versions supported by the client and server match.

  4. Verify that the correct cipher suites are being used.

  5. Check for any firewall or network configurations that might block the SSL/TLS traffic.

    network configurations

  6. Contact the administrator of the remote host to check if there are any issues on the server side.

Suraj P avatar
Suraj P avatar

A technophile and a Big Data developer by passion. Loves developing advance C++ and Java applications in free time works as SME at Chegg where I help students with there doubts and assignments in the field of Computer Science.

LinkedIn
GitHub

Related Article — Java Error

  • Fix the Error: Failed to Create the Java Virtual Machine
  • Fix the Missing Server JVM Error in Java
  • Fix the ‘No Java Virtual Machine Was Found’ Error in Eclipse
  • Fix the Error: Failed to Create the Java Virtual Machine
  • Java.Lang.VerifyError: Bad Type on Operand Stack

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and
privacy statement. We’ll occasionally send you account related emails.

Already on GitHub?
Sign in
to your account

Comments

@dhiren-mudgil-olx

Hi @johanhaleby ,

I am executing tests in multithreaded environment and i am getting below exception. Just for your info i have relaxed https validations.

RestAssured.baseURI = environmentInfoObj.getBaseUrl();
RestAssured.useRelaxedHTTPSValidation();

«Remote host closed connection during handshake.»

@johanhaleby

Rest assured is not yet safe to use in multithreaded environments. Please help out by providing pull requests or create issues for the individual problems you’re experiencing.

@dhiren-mudgil-olx

The exact stack trace of the problem is

javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:992) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387) at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:553) at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:412) at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:179) at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:328) at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:612) at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:447) at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:884) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:55) at org.apache.http.client.HttpClient$execute$2.call(Unknown Source) at io.restassured.internal.RequestSpecificationImpl$RestAssuredHttpBuilder.doRequest(RequestSpecificationImpl.groovy:2035) at io.restassured.internal.http.HTTPBuilder.doRequest(HTTPBuilder.java:494) at io.restassured.internal.http.HTTPBuilder.request(HTTPBuilder.java:451) at io.restassured.internal.http.HTTPBuilder$request$10.call(Unknown Source) at io.restassured.internal.RequestSpecificationImpl.sendHttpRequest(RequestSpecificationImpl.groovy:1441) at sun.reflect.GeneratedMethodAccessor489.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1212) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1021) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:812) at io.restassured.internal.RequestSpecificationImpl.invokeMethod(RequestSpecificationImpl.groovy) at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.call(PogoInterceptableSite.java:48) at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.callCurrent(PogoInterceptableSite.java:58) at io.restassured.internal.RequestSpecificationImpl.sendRequest(RequestSpecificationImpl.groovy:1228) at sun.reflect.GeneratedMethodAccessor329.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1212) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1021) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:812) at io.restassured.internal.RequestSpecificationImpl.invokeMethod(RequestSpecificationImpl.groovy) at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.call(PogoInterceptableSite.java:48) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:149) at io.restassured.internal.filter.SendRequestFilter.filter(SendRequestFilter.groovy:30) at io.restassured.filter.Filter$filter$8.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) at io.restassured.filter.Filter$filter$1.call(Unknown Source) at io.restassured.internal.filter.FilterContextImpl.next(FilterContextImpl.groovy:72) at io.restassured.filter.time.TimingFilter.filter(TimingFilter.java:56) at io.restassured.filter.Filter$filter$1.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) at io.restassured.filter.Filter$filter$1.call(Unknown Source) at io.restassured.internal.filter.FilterContextImpl.next(FilterContextImpl.groovy:72) at io.restassured.filter.log.StatusCodeBasedLoggingFilter.filter(StatusCodeBasedLoggingFilter.java:93) at io.restassured.filter.log.ResponseLoggingFilter.filter(ResponseLoggingFilter.java:31) at io.restassured.filter.Filter$filter$1.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) at io.restassured.filter.Filter$filter$1.call(Unknown Source) at io.restassured.internal.filter.FilterContextImpl.next(FilterContextImpl.groovy:72) at io.restassured.filter.log.RequestLoggingFilter.filter(RequestLoggingFilter.java:124) at io.restassured.filter.Filter$filter$1.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48) at io.restassured.filter.Filter$filter$8.call(Unknown Source) at io.restassured.internal.filter.FilterContextImpl.next(FilterContextImpl.groovy:72) at io.restassured.filter.FilterContext$next$9.call(Unknown Source) at io.restassured.internal.RequestSpecificationImpl.applyPathParamsAndSendRequest(RequestSpecificationImpl.groovy:1638) at sun.reflect.GeneratedMethodAccessor199.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1212) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1021) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:812) at io.restassured.internal.RequestSpecificationImpl.invokeMethod(RequestSpecificationImpl.groovy) at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.call(PogoInterceptableSite.java:48) at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.callCurrent(PogoInterceptableSite.java:58) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:182) at io.restassured.internal.RequestSpecificationImpl.applyPathParamsAndSendRequest(RequestSpecificationImpl.groovy:1644) at sun.reflect.GeneratedMethodAccessor564.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1212) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1021) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:812) at io.restassured.internal.RequestSpecificationImpl.invokeMethod(RequestSpecificationImpl.groovy) at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.call(PogoInterceptableSite.java:48) at org.codehaus.groovy.runtime.callsite.PogoInterceptableSite.callCurrent(PogoInterceptableSite.java:58) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:182) at io.restassured.internal.RequestSpecificationImpl.get(RequestSpecificationImpl.groovy:167) at io.restassured.internal.RequestSpecificationImpl.get(RequestSpecificationImpl.groovy) at utils.ApiUtil.makeGETRequest(ApiUtil.java:139) at utils.ApiUtil.makeRequest(ApiUtil.java:34) at i2.api.homepage.BindAndroid.bindAndroid(BindAndroid.java:38) at i2.api.homepage.BindAndroid.bindAndroidDeviceWithToken(BindAndroid.java:45) at i2.apitests.myaccount.AdPreviewApi.beforeMethodSetup(AdPreviewApi.java:45) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:86) at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:514) at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:215) at org.testng.internal.Invoker.invokeMethod(Invoker.java:589) at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:820) at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1128) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112) at org.testng.TestRunner.privateRun(TestRunner.java:782) at org.testng.TestRunner.run(TestRunner.java:632) at org.testng.SuiteRunner.runTest(SuiteRunner.java:366) at org.testng.SuiteRunner.access$000(SuiteRunner.java:39) at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:400) at org.testng.internal.thread.ThreadUtil$2.call(ThreadUtil.java:64) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) 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:973) ... 118 more

@dhiren-mudgil-olx

@johanhaleby

@dhirenmudgil Thanks for sharing. I don’t believe this to be a bug then.

@gvijaysankar

Hi All,
Please go through the below Video, below issues would be resolved.
javax.net.ssl.SSLHandshakeException / javax.net.ssl.SSLHandshakeExceptionRemote host closed connection during handshake / Fatal transport error: Remote host closed connection during handshake

https://youtu.be/6v673WsbJis

@zigri2612

You can set protocol versions in system property as :
overcome ssl handshake error
System.setProperty(«https.protocols», «TLSv1,TLSv1.1,TLSv1.2»);

Еще не ответ, но слишком много для комментария. Это явно не проблема сертификата сервера; симптомы этого совершенно разные. Из вашей системы POV сервер, кажется, закрывается во время рукопожатия. Возможны две возможности:

Сервер действительно закрывается, что является нарушением протокола SSL/TLS, хотя и довольно незначительным; существует немало причин, по которым сервер может не согласиться с вами, но он должен сначала отправить фатальное предупреждение, которое должно указывать ваш JSSE или эквивалент weblogic. В этом случае может быть некоторая полезная информация в журнале сервера, если вы можете (и разрешено) связываться со знающим администратором сервера (ов). Или вы можете попробовать разместить сетевой монитор на своей клиентской машине или один достаточно близко, чтобы увидеть весь свой трафик; лично мне нравится www.wireshark.org. Но это обычно показывает только, что закрытие произошло сразу после ClientHello, что не сильно сужает его. Вы не говорите, хотите ли вы и настроили «клиентский сертификат» (на самом деле key & cert, в форме Java privateKeyEntry) для этого сервера; если это требуется сервером, а не правильно, некоторые серверы могут воспринимать это как атаку и сознательно нарушать протокол, закрывая, хотя официально они должны отправить предупреждение.

Или, какой-то средний ящик в сети, чаще всего брандмауэр или якобы прозрачный прокси, решает, что ему не нравится ваше соединение и заставляет закрыть. Прокси, который вы используете, является очевидным подозреваемым; когда вы говорите, что «тот же код» работает с другими хостами, подтвердите, означает ли вы через тот же прокси (а не только прокси) и используете HTTPS (непонятный HTTP). Если это не так, попробуйте протестировать другие хосты с помощью HTTPS через прокси (вам не нужно отправлять полный запрос SOAP, просто GET/if enough). Если вы можете, попробуйте подключиться без прокси-сервера или, возможно, другого прокси-сервера, и подключить HTTP (не S) через прокси-сервер к хосту (если обе поддержки ясны) и посмотреть, работают ли они.

Если вы не возражаете опубликовать фактический хост (но определенно не какие-либо учетные данные), другие могут попробовать его. Или вы можете зайти на сайт www.ssllabs.com и попросить их протестировать сервер (без публикации результатов); это попробует несколько общих вариантов соединения SSL/TLS и сообщит о любых обнаруженных ошибках, а также о любых слабых сторонах безопасности.

  • Remote desktop произошла внутренняя ошибка
  • Remote control ошибка бмв
  • Remote access ошибка 20106
  • Remote access 20063 ошибка
  • Remnant from the ashes при проверке доступа к сетевым функциям возникла неизвестная ошибка egs