带有 TLS 1.3 的 Java 11 SSLHandshakeException:如何恢复到 TLS 1.2?

Soh*_*ham 6 java ssl tls1.2 java-11

我的应用程序是一种“网络爬虫”形式,它使用Java Jsoup 库从所需的输入页面加载 HTML 。我最近将我的应用程序平台从 Java 8 升级到了 Java 11。通过这次升级,我收到了一些客户的报告,说他们在尝试加载某些网页的 HTML 内容时收到 SSLHandshakeExceptions。这些出现的网页因设备而异,在某些设备上,我的客户端根本无法加载任何网页(http:// 和 https:// 网页都没有)。

我尝试通过多种方式解决此问题,但无济于事:

  1. 用 Java 8 运行时的 CACERT 文件替换 Java 11 运行时的 CACERT 文件
  2. 创建一个自定义 SSL 证书接受器,无论有效性如何,它都接受所有 SSL 证书(我知道这对生产代码不利,但这仅用于测试目的)-请参阅通过 HTTPS 使用 HttpClient 信任所有证书

在这一点上,我不确定要采取哪些选择,因为我对 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 的原因。我该怎么做呢?

ixe*_*013 6

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

java -Djdk.tls.client.protocols=TLSv1.2 -jar ... <rest of command line here>
Run Code Online (Sandbox Code Playgroud)

它将使您的客户端仅宣传 TLS 版本 1.2,并使用该版本,即使您要连接的服务器支持 TLS 1.3


dav*_*085 5

使用 Jsoup 时, Neardupe Java 11 HTTPS 连接失败并出现 SSL HandshakeException ,但我有一些需要补充的内容。

使用Connection.sslSocketFactory(factory)和合适的参数。SSLContext.getInstance("TLSv1.2")假设使用标准/默认提供程序,您可以使用可能使用默认 trustmanager 和 keymanager ie创建的工厂.init(null,null,null)

或者根据JSSE 文档中的表 8-3设置jdk.tls.client.protocols或。请注意,这可能会影响从同一 JVM 建立的任何其他 SSL/TLS 连接或 HTTPS 的其他 URLConnection。https.protocols

不过,如果这能解决您的问题,我会感到惊讶。TLS1.3 被推迟了数年,部分原因是他们添加了黑客攻击,因此它不会在旧版 1.2(甚至更早的)系统和“盒子”上失败。