解决 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 驱动允许从服务器检索公钥,从而完成认证。

步骤:

  1. 找到你的 JDBC 连接 URL。通常它看起来像这样:
    jdbc:mysql://127.0.0.1:3306/你的数据库名?一些参数
    
  2. 在 URL 的末尾添加 &allowPublicKeyRetrieval=true
  3. 示例完整的 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,这样就不需要公钥检索了。

步骤:

  1. 登录 MySQL 服务器,使用 root 或有权限的用户。
  2. 执行以下 SQL 命令(基于你提供的例子,假设用户是 root,密码是 123456):
    ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';
    FLUSH PRIVILEGES;
    ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';
    
  3. 解释每个命令:
    • 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 相关讨论

写文章用