带有 TLS 1.3 的 Java 11 SSLHandshakeException:如何恢复到 TLS 1.2?
Posted
技术标签:
【中文标题】带有 TLS 1.3 的 Java 11 SSLHandshakeException:如何恢复到 TLS 1.2?【英文标题】:Java 11 SSLHandshakeException with TLS 1.3: How do I revert to TLS 1.2? 【发布时间】:2020-07-12 06:39:18 【问题描述】:我的应用程序是一种“网络爬虫”形式,它使用the Java Jsoup library 从所需的输入页面加载 html。我最近将我的应用程序平台从 Java 8 升级到 Java 11。通过这次升级,我收到了几份来自客户的报告,称他们在尝试加载某些网页的 HTML 内容时收到 SSLHandshakeExceptions。这些出现的网页因设备而异,在某些设备上,我的客户端根本无法加载任何网页(http:// 和 https:// 网页都没有)。
我尝试了多种方式解决此问题,但无济于事:
-
用 Java 8 运行时的 CACERT 文件替换 Java 11 运行时的 CACERT 文件
创建一个自定义 SSL 证书接受器,它接受所有 SSL 证书而不管其有效性(我知道这对生产代码不利,但这只是为了测试目的) - 请参阅 Trusting all certificates using HttpClient over HTTPS
在这一点上,我不太确定可以采取哪些选择,因为我对 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 的原因。我该怎么做?
【问题讨论】:
【参考方案1】:Neardupe Java 11 HTTPS connection fails with SSL HandshakeException while using Jsoup 但我有一些要补充的。
将Connection.sslSocketFactory(factory) 与合适的参数一起使用。假设标准/默认提供程序,您可以使用从SSLContext.getInstance("TLSv1.2")
创建的工厂,可能带有默认的信任管理器和密钥管理器,即.init(null,null,null)
。
或在the JSSE documentation 中为每个表8-3 设置jdk.tls.client.protocols
或https.protocols
。请注意,这可能会影响任何其他 SSL/TLS 连接,或其他用于 HTTPS 的 URLConnection,由同一 JVM 制成。
不过,如果这能解决您的问题,我会感到惊讶。 TLS1.3 延迟年部分是因为他们添加了 hack,因此它不会在旧版 1.2(甚至更早的)系统和“盒子”上失败。
【讨论】:
SSLContext.getInstance("TLSv1.2") 为我工作。这是我使用的代码片段:pastebin.com/FCzj7gK0。谢谢。【参考方案2】:您还可以在 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 也使用该版本
【讨论】:
【参考方案3】:仅供参考: 此 TLS1.3 错误是 11.0.2 之前的 JDK11 中的一个已知错误。 https://bugs.openjdk.java.net/browse/JDK-8211806
【讨论】:
以上是关于带有 TLS 1.3 的 Java 11 SSLHandshakeException:如何恢复到 TLS 1.2?的主要内容,如果未能解决你的问题,请参考以下文章
在 IIS 10 windows server 2019 上启用 TLS 1.3
小心了!前程无忧百万条用户信息外泄?暗网售价50万;JDK 11 还有一个处于计划阶段的 JEP:让其支持 TLS 1.3