问题描述
在 2021 年 4 月对 JDK 的最新更新 (11.0.11+9-0ubuntu2~18.04
) 中,支持 TLSv1
和 TLSv1.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).
注意:如果您想从 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:没有合适的协议)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!