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 . java.security
文件中的差异可以证明这一点:
前:
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 版本以来的最后几天也弹出了更多答案。
更新 JDK 后,我们收到错误
java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.
与 c3p0
。
切换到 hikari
之后,我们得到了一个更有意义的错误:
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
。
那么问题来了,为什么 JDK 和 MySQL 不同意使用 TLSv1.2
我们能做些什么,让它们与 TLSv1.2
通信?
注意:我不认为按照其他线程中的建议更改 java.security
文件是解决此问题的良好长期解决方案!
原文由 bersling 发布,翻译遵循 CC BY-SA 4.0 许可协议
正如@skelwa 已经评论过的,您需要在连接字符串中添加
enabledTLSProtocols=TLSv1.2
配置属性来解决您的问题。Connector/J 的完整连接字符串可能如下所示:
对于 r2dbc ,您需要使用
tlsVersion=TLSv1.2
代替。对于 Connector/J v8.0.28
enabledTLSProtocols
已重命名为tlsVersions
(见 注释)。但是,原始名称仍然作为别名。剩下的问题是:
为什么 JDK 和 MySQL 不同意使用
TLSv1.2
?尽管双方实际上都支持 TLSv1.2,但您遇到的问题是由 Connector/J 的默认行为引入的。出于兼容性原因,Connector/J 默认不启用 TLSv1.2 及更高版本。因此,必须明确启用它。
请参阅以下 注释:
警告: 请注意,建议编辑
jdk.tls.disabledAlgorithms
内部jre/lib/security
的解决方案会给您的应用程序带来 _安全风险_,并且更改那里的任何内容都可能会产生严重影响!这些协议被禁用是有原因的,不应该简单地从该列表中删除所有内容甚至部分内容。注意: 如果你想从 JDK 获得更多低级别的洞察力来调试你的问题,你可以通过将以下配置传递给 java 命令来启用 ssl 调试日志:
-Djavax.net.debug=ssl,handshake
甚至-Djavax.net.debug=all
在您的情况下,您会看到类似以下内容: