解决 MySQL 连接错误:Public Key Retrieval is not allowed
大家好,我是 gwozai。作为一名后端开发者,我经常在项目中遇到各种数据库连接问题。今天,我想和大家分享一个常见的 MySQL 错误:“Public Key Retrieval is not allowed”。这个错误通常出现在使用 JDBC 驱动连接 MySQL 数据库时,尤其是 MySQL 8.0 及以上版本。如果你也遇到了这个问题,别担心,我会一步步解释它的原因,并提供两种简单有效的解决方案。让我们开始吧!
错误原因分析
首先,我们来了解一下这个错误为什么会出现。“Public Key Retrieval is not allowed” 翻译成中文是“公共密钥检索不允许”。这个错误与 MySQL 的安全机制有关。
- 背景:从 MySQL 8.0 开始,默认的认证插件从
mysql_native_password改为caching_sha2_password。这种新插件使用更安全的 SHA-256 加密,但它要求客户端在连接时检索服务器的公钥(Public Key)来验证密码。 - 问题触发:当你的 JDBC 驱动(例如 mysql-connector-java)尝试连接 MySQL 时,如果没有明确允许公钥检索,或者服务器配置不允许,就会抛出这个错误。这通常发生在:
- 使用旧版 JDBC 驱动(不支持 caching_sha2_password)。
- 连接字符串中缺少相关参数。
- 安全考虑,默认禁用公钥检索以避免潜在的中间人攻击。
简单来说,这个错误是 MySQL 为了增强安全性而引入的,但它可能会中断你的应用连接。如果你看到类似这样的异常栈:
com.mysql.cj.exceptions.CJCommunicationsException: Public Key Retrieval is not allowed
那就是它了!接下来,我分享两种修复方法。第一种是客户端侧的快速修复,第二种是服务器侧的永久修改。
方法一:修改 JDBC 连接 URL
这是最简单、非侵入性的方法。你只需要在连接字符串(URL)中添加一个参数:allowPublicKeyRetrieval=true。这个参数告诉 JDBC 驱动允许从服务器检索公钥,从而完成认证。
步骤:
- 找到你的 JDBC 连接 URL。通常它看起来像这样:
jdbc:mysql://127.0.0.1:3306/你的数据库名?一些参数 - 在 URL 的末尾添加
&allowPublicKeyRetrieval=true。 - 示例完整的 URL(基于你提供的例子):
jdbc:mysql://127.0.0.1:3306/gaoxiaowupinjuanzeng?useUnicode=true&characterEncoding=utf-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=true
为什么有效?
- 这个参数启用公钥检索,允许客户端安全地获取服务器的 RSA 公钥。
- 注意:如果你的环境有安全顾虑(如公共网络),最好结合
useSSL=true使用,以加密连接。但在本地开发中,useSSL=false是常见的。
优缺点:
- 优点:无需修改数据库服务器配置,立即生效。
- 缺点:如果有多个应用连接,需要在每个地方都添加参数;潜在的安全风险(如果不启用 SSL)。
测试一下:重启你的应用或重新连接,应该就能正常访问数据库了!
方法二:更改 MySQL 用户认证插件
如果方法一不适合(比如你不想修改所有客户端的 URL),可以从服务器端入手。将用户的认证插件改回旧版的 mysql_native_password,这样就不需要公钥检索了。
步骤:
- 登录 MySQL 服务器,使用 root 或有权限的用户。
- 执行以下 SQL 命令(基于你提供的例子,假设用户是 root,密码是 123456):
ALTER USER 'root'@'localhost' IDENTIFIED BY '123456'; FLUSH PRIVILEGES; ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456'; - 解释每个命令:
ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';:设置或重置密码。FLUSH PRIVILEGES;:刷新权限,使更改立即生效。ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';:将认证插件改为mysql_native_password,并设置密码。
为什么有效?
mysql_native_password是 MySQL 5.x 的默认插件,不依赖公钥检索。它使用简单的 SHA1 加密,兼容旧版驱动。- 这会永久解决错误,除非你升级或重置用户。
优缺点:
- 优点:服务器侧一次性修改,所有客户端受益;兼容旧版应用。
- 缺点:降低了安全性(SHA1 不如 SHA-256 安全);需要数据库管理员权限。
注意:替换 'root'@'localhost' 为你的实际用户名和主机。如果是远程连接,可能需要 'root'@'%'。
总结与建议
“Public Key Retrieval is not allowed” 是一个常见的 MySQL 8+ 兼容性问题,但通过以上两种方法,你可以轻松解决。方法一适合快速修复,方法二适合长期配置。如果你还在使用旧版 JDBC 驱动,建议升级到最新版(例如 8.0+),以获得更好的支持。
如果你的项目涉及生产环境,优先考虑安全:启用 SSL 并使用 caching_sha2_password。如果你有其他问题,比如时区或编码错误(从你的 URL 看,你已经处理了),欢迎在评论区留言讨论!
感谢阅读!我是 gwozai,下次见。😊
参考资料:
- MySQL 官方文档:Authentication Plugins
- Stack Overflow 相关讨论