为什么Java在最新的JDK更新后无法连接到MySQL 5.7,应该如何修复?(ssl.SSLHandshakeException:没有合适的协议) [英] Why can Java not connect to MySQL 5.7 after the latest JDK update and how should it be fixed? (ssl.SSLHandshakeException: No appropriate protocol)

查看:321
本文介绍了为什么Java在最新的JDK更新后无法连接到MySQL 5.7,应该如何修复?(ssl.SSLHandshakeException:没有合适的协议)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 2021 年 4 月对 JDK 的最新更新 (11.0.11+9-0ubuntu2~18.04) 中,支持 TLSv1TLSv1.1 被删除,大概是因为自 2021 年 3 月起不再支持这些版本.java.security 文件中的差异很明显:

In the latest update to the JDK in April 2021 (11.0.11+9-0ubuntu2~18.04) support for TLSv1 and TLSv1.1 was dropped, presumably because since March 2021 those versions are no longer supported. This is evident by the diff in the java.security file:

之前:

jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, DH keySize < 1024, \
    EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
    include jdk.disabled.namedCurves

之后:

jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \
    DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
    include jdk.disabled.namedCurves

这也在这个 SO 帖子中讨论:SSLHandShakeException No Appropriate Protocol.在该线程中,自 JDK 版本更新以来的最后几天也出现了更多答案.

which is also discussed in this SO post: SSLHandShakeException No Appropriate Protocol . In that thread there are also more answers popping up the last few days since the updated JDK version.

这次更新JDK后,我们收到错误

After this update of the JDK, we received the error

java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.

使用 c3p0.

切换到 hikari 后,我们得到了一个更有意义的错误:

After switching to hikari we got a more meaningful error:

ERROR [2021-04-29 16:21:16,426] com.zaxxer.hikari.pool.HikariPool: HikariPool-1 - Exception during pool initialization.
! javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

我们在 MySQL 5.7.33-0ubuntu0.18.04.1 上运行.现在按照我的理解,这里, MySQL 5.7 支持 TLSv1.2.同样在运行 SHOW VARIABLES LIKE 'tls_version'; 时,我们得到 TLSv1,TLSv1.1,TLSv1.2 这表明支持 TLSv1.2.

We're running on MySQL 5.7.33-0ubuntu0.18.04.1. Now in my understanding as described here, MySQL 5.7 supports TLSv1.2. Also when running SHOW VARIABLES LIKE 'tls_version'; we get TLSv1,TLSv1.1,TLSv1.2 which suggest that TLSv1.2 is supported.

那么问题是,为什么 JDK 和 MySQL 不就使用 TLSv1.2 达成一致,我们可以做些什么,使它们与 TLSv1.2 通信?

So then the question is, why don't the JDK and MySQL just agree on using TLSv1.2 and what can we do about it, to make them communicate with TLSv1.2?

注意:我不认为按照另一个线程的建议更改 java.security 文件是解决此问题的良好长期解决方案!

Note: I don't think changing the java.security file as suggested in the other thread is a good long term solution to this problem!

推荐答案

正如@skelwa 已经评论过的,您需要在连接字符串中添加 enabledTLSProtocols=TLSv1.2 配置属性来解决您的问题.完整的连接字符串可能如下所示:

As @skelwa already commented you will need to add the enabledTLSProtocols=TLSv1.2 configuration property in the connection string to resolve your issue. A complete connection string could look like this:

jdbc:mysql://<host>:<port>/<dbname>?enabledTLSProtocols=TLSv1.2

剩下的问题是:

为什么 JDK 和 MySQL 不同意使用 TLSv1.2?

虽然双方实际上都支持 TLSv1.2,但您遇到的问题是由 Connector/J 的默认行为引入的.出于兼容性原因,Connector/J 默认不启用 TLSv1.2 及更高版本.因此,必须明确启用它.

Although both parties do actually support TLSv1.2, the problem you were experiencing is introduced by the default behavior of the Connector/J. For compatibility reasons the Connector/J does not enable TLSv1.2 and higher by default. Therefore, one has to enable it explicitly.

见以下注意:

对于连接到 MySQL 社区时的 Connector/J 8.0.18 及更早版本使用 JDBC API 的服务器 5.6 和 5.7:由于兼容性问题使用 yaSSL 编译的 MySQL 服务器,Connector/J 不启用默认情况下与 TLSv1.2 及更高版本的连接.当连接到限制连接使用那些更高 TLS 版本的服务器,通过设置 Connector/J 连接属性显式启用它们enabledTLSProtocols(例如,设置enabledTLSProtocols=TLSv1,TLSv1.1,TLSv1.2).

For Connector/J 8.0.18 and earlier when connecting to MySQL Community Server 5.6 and 5.7 using the JDBC API: Due to compatibility issues with MySQL Server compiled with yaSSL, Connector/J does not enable connections with TLSv1.2 and higher by default. When connecting to servers that restrict connections to use those higher TLS versions, enable them explicitly by setting the Connector/J connection property enabledTLSProtocols (e.g., set enabledTLSProtocols=TLSv1,TLSv1.1,TLSv1.2).


注意:如果您想从 JDK 获得更多低级见解来调试您的问题,您可以通过将以下配置传递给 java 命令来启用 ssl 调试日志:


Note: if you want to get more low level insights from the JDK to debug your problem you can enable ssl debug logs by passing the following configuration to the java comand:

-Djavax.net.debug=ssl,handshake甚至-Djavax.net.debug=all

在您的情况下,您将看到如下内容:

In your case you will see something like:

...(HANDSHAKE_FAILURE): Couldn't kickstart handshaking (
"throwable" : {
  javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
    at java.base/sun.security.ssl.HandshakeContext.<init>(HandshakeContext.java:170)
    at java.base/sun.security.ssl.ClientHandshakeContext.<init>(ClientHandshakeContext.java:98)
    ...

这篇关于为什么Java在最新的JDK更新后无法连接到MySQL 5.7,应该如何修复?(ssl.SSLHandshakeException:没有合适的协议)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆