Java 11中使用TLS 1.3发生SSLHandshakeException错误:如何恢复到TLS 1.2?

10

我的应用程序是一种“网页爬虫”,使用Java Jsoup库从所需的输入页面加载HTML。我最近将应用程序平台从Java 8升级到了Java 11。随着这个升级,我收到了几份来自客户的报告,称他们在尝试加载某些网页的HTML内容时收到了SSLHandshakeExceptions错误。出现这种情况的网页因设备而异,在某些设备上,我的客户无法加载任何网页(http://和https://网页都不行)。

我已经尝试了几种方法来解决这个问题,但都没有成功:

  1. 将Java 11运行时的CACERT文件替换为Java 8运行时的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的原因。我该如何做到这一点?

3个回答

6

您还可以在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的服务器时仍然使用该版本。


5

我有一些可以添加的内容,类似于Java 11 HTTPS connection fails with SSL HandshakeException while using Jsoup。使用适当的参数Connection.sslSocketFactory(factory)。假设使用标准/默认提供程序,则可以使用从SSLContext.getInstance("TLSv1.2")创建的工厂,可能带有默认的trustmanager和keymanager,即.init(null,null,null)

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

虽然我会感到惊讶,但我不认为这会解决你的问题。TLS1.3被推迟了数年,部分原因是添加了一些黑客技术,以便它在旧的1.2(甚至更早)系统和“盒子”上不会失败。


1
SSLContext.getInstance("TLSv1.2") 对我有效。这是我使用的代码片段:https://pastebin.com/FCzj7gK0。谢谢。 - Soham

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接