java - Spring 引导中的 TLSv1.2 错误

标签 java spring ssl spring-boot

在 spring boot 中进行 ssl 连接时出现错误。

http-nio-8081-exec-1, WRITE: TLSv1.2 Handshake, length = 193
[Raw write]: length = 198
0000: 16 03 03 00 C1 01 00 00   BD 03 03 59 0F F5 50 BA  ...........Y..P.
0010: AC 01 0A A6 F9 AB 1C C6   B5 50 B1 4E 2A 0E D2 4B  .........P.N*..K
0020: C1 7C 75 7B 90 70 A3 6A   20 30 C1 00 00 3A C0 23  ..u..p.j 0...:.#
0030: C0 27 00 3C C0 25 C0 29   00 67 00 40 C0 09 C0 13  .'.<.%.).g.@....
0040: 00 2F C0 04 C0 0E 00 33   00 32 C0 2B C0 2F 00 9C  ./.....3.2.+./..
0050: C0 2D C0 31 00 9E 00 A2   C0 08 C0 12 00 0A C0 03  .-.1............
0060: C0 0D 00 16 00 13 00 FF   01 00 00 5A 00 0A 00 34  ...........Z...4
0070: 00 32 00 17 00 01 00 03   00 13 00 15 00 06 00 07  .2..............
0080: 00 09 00 0A 00 18 00 0B   00 0C 00 19 00 0D 00 0E  ................
0090: 00 0F 00 10 00 11 00 02   00 12 00 04 00 05 00 14  ................
00A0: 00 08 00 16 00 0B 00 02   01 00 00 0D 00 18 00 16  ................
00B0: 06 03 06 01 05 03 05 01   04 03 04 01 03 03 03 01  ................
00C0: 02 03 02 01 02 02                                  ......
http-nio-8081-exec-1, handling exception: java.net.SocketException: Connection reset
http-nio-8081-exec-1, SEND TLSv1.2 ALERT:  fatal, description = unexpected_message
http-nio-8081-exec-1, WRITE: TLSv1.2 Alert, length = 2
http-nio-8081-exec-1, Exception sending alert: java.net.SocketException: Connection reset by peer: socket write error
http-nio-8081-exec-1, called closeSocket()
[2m2017-05-08 14:26:40.714[0;39m [31mERROR [CS Facade,,,][0;39m [35m6360[0;39m [2m---[0;39m [2m[nio-8081-exec-1][0;39m [36mo.a.c.c.C.[.[.[/].[dispatcherServlet]   [0;39m [2m:[0;39m Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.client.ResourceAccessException: I/O error on GET request for "<URL>": Connection reset; nested exception is java.net.SocketException: Connection reset] with root cause

java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at sun.security.ssl.InputRecord.readFully(Unknown Source)
    at sun.security.ssl.InputRecord.read(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.connect(Unknown Source)
    at org.springframework.http.client.SimpleBufferingClientHttpRequest.executeInternal(SimpleBufferingClientHttpRequest.java:78)
    at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
    at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:652)    

尝试在 JVM 参数中设置

-Dhttps.protocols="TLSv1.2,TLSv1.1,TLSv1,SSLv3"

也尝试在application.properties中设置

server.ssl.protocol=TLS

我已经以编程方式启用了 ssl

@Bean
  public EmbeddedServletContainerFactory servletContainer() {
      TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
      tomcat.addAdditionalTomcatConnectors(createStandardConnector());
      return tomcat;
  }

  private Connector createStandardConnector() {
      Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
      connector.setPort(Integer.valueOf(port));
      return connector;
  }

提到是java版本的问题 SSL Connection Reset

我正在使用 java 版本“1.8.0_91”和 spring boot:1.5.2.RELEASE

是不是因为server jks文件是老版本的java生成的?请提供一些关于这个问题的见解。

最佳答案

一些见解(我希望)但不是答案:

您链接的 Q 中的问题是 Java 版本 6,它在 2011 年初仍然是最新的,并且默认情况下尝试与 SSLv2 格式协商(尽管即使是 6 也不会实际协商 SSLv2 < em>协议(protocol))。您使用默认为现代格式和最大协议(protocol) TLSv1.2 的 8,并且您的 Q 中的跟踪证实了这一点(ClientHello 提供线路版本 0303,即 TLSv1.2),并且由于 1.3 尚未推出,因此没有合理的服务器需要更多草稿。错误的版本或格式只是 SSL/TLS 握手期间重置的一个可能原因;还有很多。

最近的 Java 8 默认 https.protocols 为 TLSv1.2、TLSv1.1、TLSv1(.0)。添加 SSLv3 不是一个好主意;自 2011 年以来(以及自“8u0”以来),它已被破坏。任何实际协商 SSLv3 的服务器都可能由不称职的人操作,不应使用。

Tomcat 连接器是关于传入 HTTP 和/或 HTTPS (TLS) 连接的。它与传出 连接无关。

来自旧版本 Java 的 JKS 文件没有问题,除非旧版本使用非标准加密提供程序而更新/当前版本不使用,并且在任何情况下 server.jks 同样适用于传入连接而不是传出连接,加上任何 keystore 问题会在发送 ClientHello 消息之前或在收到服务器的 Certificate 消息之后发生,您的跟踪和堆栈跟踪都相互矛盾。

最好的办法是从服务器中找出它不喜欢的东西——直接像日志一样或通过它的运算符(operator)。

但是,我通过查看看到了一种可能性——您的堆栈没有发送 ServerNameIndication aka SNI。这在技术上是 TLS 中的一个选项,但近年来许多服务器程序(和服务器)已经开始要求它,尽管为此原因拒绝 Hello 的服务器应该使用警报而不是重置。 Java 8 应该自动为 HttpsUrlConnection 发送 SNI,除非某人或某物将系统属性 jsse.enableSNIExtension 配置为 false 或者 URL 的主机名部分是单个“标签”(无点)或 IP 地址 - - 你在做这些吗?

关于java - Spring 引导中的 TLSv1.2 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43839896/

相关文章:

Java数学计算中的错误

java - Java中的自定义号码

java - 使用Java与控制台(Linux中的终端)窗口交互

java - 如何在 Thymeleaf 中动态替换片段?

java - Spring Boot使用pathvariable从url获取id

java - 错误由: java. lang.ClassNotFoundException : org. springframework.security.context.DelegatingApplicationListener引起

java - 使用 XPath 单击超文本链接

tomcat - 如何确定上传连接是否安全 (ssl)?

ssl - 适用于 MDM 的 Apple 推送通知服务

amazon-web-services - 将 AWS RDS SSL/TLS 证书从 rds-ca-2015 更新为 rds-ca-2019