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



我的应用程序是一种"web scraper"形式,它使用Java Jsoup库从所需的输入页面加载HTML。我最近将我的应用程序平台从Java 8升级到了Java 11。通过这次升级,我收到了几份来自客户的报告,称他们在尝试加载某些网页的HTML内容时收到了SSLHandshakeException。这些网页出现在不同的设备上,在某些设备上,我的客户端根本无法加载任何网页(无论是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,因为我认为这是SSLHandshakeException的原因。我该怎么做

您还可以在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

Neardupe Java 11 HTTPS连接在使用Jsoup时失败,出现SSL HandshakeException,但我还有一些要添加的内容。

使用带有适当参数的Connection.sslSocketFactory(工厂(。假设是标准/默认提供程序,您可以使用从SSLContext.getInstance("TLSv1.2")创建的工厂,可能带有默认的信任管理器和密钥管理器,即.init(null,null,null)

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

不过,如果这能解决你的问题,我会感到惊讶。TLS1.3被推迟了,部分原因是他们添加了黑客,因此它不会因遗留1.2(甚至更早(系统和"盒子"而失败。

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

最新更新