Java 11 SSLHandshakeException with TLS 1.3:如何恢复到 TLS 1.2?

Java 11 SSLHandshakeException with TLS 1.3: How do I revert to TLS 1.2?

我的应用程序是 "web scraper" 的一种形式,它使用 the Java Jsoup library 从所需的输入页面加载 HTML。我最近将我的应用程序平台从 Java 8 升级到 Java 11。通过这次升级,我收到了几份来自客户的报告,称他们在尝试加载 HTML 的内容时收到 SSLHandshakeExceptions某些网页。这些网页因设备而异,在某些设备上,我的客户根本无法加载任何网页(http:// 和 https:// 网页)。

我试过几种方法解决这个问题,但无济于事:

  1. 将 Java 11 运行时的 CACERT 文件替换为 Java 8 运行时的 CACERT 文件
  2. 创建一个接受所有 SSL 证书而不考虑有效性的自定义 SSL 证书接受器(我知道这对生产代码不利,但这只是为了测试目的)- 参见

在这一点上,我不太确定该选择什么选项,因为我对 SSL、TLS 和 HTTPS 的了解有限。这些错误从未发生在 Java 8 中,并且在升级到 Java 11 之前一切正常。

据我了解,Java 11 对 SSL 的唯一更改是升级到 TLS 1.3,而之前的 Java 版本依赖于使用 TLS 1.2。

因此,我想强制 Java 11 使用 TLS 1.2 而不是 TLS 1.3,因为我认为这是 SSLHandshakeExceptions 的原因。我应该怎么做?

Neardupe 但我还有一些要补充。

使用带有 suitable 参数的 Connection.sslSocketFactory(factory)。假设有 standard/default 个提供者,您可以使用从 SSLContext.getInstance("TLSv1.2") 创建的工厂,可能使用默认的 trustmanager 和 keymanager,即 .init(null,null,null)

或根据 the JSSE documentation 中的 table 8-3 设置 jdk.tls.client.protocolshttps.protocols。请注意,这可能会影响任何其他 SSL/TLS 连接,或来自同一 JVM 的其他 HTTPS URLConnection。

不过,如果这能解决您的问题,我会感到很惊讶。 TLS1.3 被延迟 部分原因是他们添加了黑客攻击,因此它 不会 在遗留 1.2(甚至更早)系统和 'boxes'.

您还可以在 Java 客户端的命令行中定义 jdk.tls.client.protocols=TLSv1.2

java -Djdk.tls.client.protocols=TLSv1.2 -jar ... <rest of command line here>

它会让您的客户端仅通告 TLS 1.2 版,并使用该版本,即使您要连接的服务器支持 TLS 1.3

仅供参考: 此 TLS1.3 错误是 JDK11 11.0.2 之前的已知错误。 https://bugs.openjdk.java.net/browse/JDK-8211806