Apache HttpClient 中的自签名证书问题
Self signed certificate issue in Apache HttpClient
我有一个网站的自签名证书。我使用 keytool 将它导入 java cacert 文件。之后,它可以很好地处理 RestTemplate 请求。
当我使用 Apache HttpClients 请求时,出现如下异常:
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
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:123)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:318)
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:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
at HttpClientRequestTest.test3(HttpClientRequestTest.java:93)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:90)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:508)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=10=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
RestTemplate代码:
final RestTemplate restTemplate = new RestTemplate();
final ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
Apache HttpClients 示例:
final HttpGet request = new HttpGet(url);
final HttpClient httpClient = HttpClients.createDefault();
final HttpResponse response = httpClient.execute(request);
有没有人知道为什么它使用 RestTemplate 但不使用 HttpClients?
HttpClient 版本为 4.5.13
当您处理 “任何(!)类型的 'crypto issue,'” 时,您需要查看日志文件,尤其是“从服务器端。”
“客户”当然是故意的,“应该绝对不会学到任何东西”,因为它被假定为“Eve-il 入侵者”,而不是“爱丽丝”或“鲍勃”。客户只感觉到门在他们面前砰的一声关上了,完全没有解释。
没有足够的信息来回答原因。
我们所知道的是终止连接的是服务器。因此,似乎是客户做错了。
这是一个好兆头,因为这意味着您可以采取一些措施:)
您提到了 CA 证书 - 我个人看不出有什么方法可以让您的服务器关心您安装的 CA 证书。这些证书用于验证服务器提供的证书。
您有几个选项可以解决:
一个。调试:使用一个很好的反编译器,比如 IntelliJ 自带的反编译器。您将挖掘到 URL 对象类型,您将看到提供的证书、收到的证书……加密算法……等等……
如果您不确定这些东西中的任何一个应该是什么,至少将它与“有效的”的调试进行比较。
乙。 TCP 跟踪。根据可用的内容,您可以使用 WireShark 查看数据。可能需要一些手动解密。
同样,与已知的良好值或至少与有效的方法进行比较
C.服务器日志。如果您可以访问这些并且它们很好,异常应该出现在这些日志之一中并告诉您客户端消息有什么问题
D.反复试验。尝试忘记您的假设并更明确地使用您的配置。可能某些东西被设置为默认值,而这不是服务器喜欢的
我有一个网站的自签名证书。我使用 keytool 将它导入 java cacert 文件。之后,它可以很好地处理 RestTemplate 请求。 当我使用 Apache HttpClients 请求时,出现如下异常:
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
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:123)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:318)
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:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
at HttpClientRequestTest.test3(HttpClientRequestTest.java:93)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:90)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:508)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=10=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
RestTemplate代码:
final RestTemplate restTemplate = new RestTemplate();
final ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
Apache HttpClients 示例:
final HttpGet request = new HttpGet(url);
final HttpClient httpClient = HttpClients.createDefault();
final HttpResponse response = httpClient.execute(request);
有没有人知道为什么它使用 RestTemplate 但不使用 HttpClients?
HttpClient 版本为 4.5.13
当您处理 “任何(!)类型的 'crypto issue,'” 时,您需要查看日志文件,尤其是“从服务器端。”
“客户”当然是故意的,“应该绝对不会学到任何东西”,因为它被假定为“Eve-il 入侵者”,而不是“爱丽丝”或“鲍勃”。客户只感觉到门在他们面前砰的一声关上了,完全没有解释。
没有足够的信息来回答原因。
我们所知道的是终止连接的是服务器。因此,似乎是客户做错了。
这是一个好兆头,因为这意味着您可以采取一些措施:)
您提到了 CA 证书 - 我个人看不出有什么方法可以让您的服务器关心您安装的 CA 证书。这些证书用于验证服务器提供的证书。
您有几个选项可以解决:
一个。调试:使用一个很好的反编译器,比如 IntelliJ 自带的反编译器。您将挖掘到 URL 对象类型,您将看到提供的证书、收到的证书……加密算法……等等…… 如果您不确定这些东西中的任何一个应该是什么,至少将它与“有效的”的调试进行比较。
乙。 TCP 跟踪。根据可用的内容,您可以使用 WireShark 查看数据。可能需要一些手动解密。 同样,与已知的良好值或至少与有效的方法进行比较
C.服务器日志。如果您可以访问这些并且它们很好,异常应该出现在这些日志之一中并告诉您客户端消息有什么问题
D.反复试验。尝试忘记您的假设并更明确地使用您的配置。可能某些东西被设置为默认值,而这不是服务器喜欢的