Public Key Retrieval is not allowed

Public Key Retrieval is not allowed

这个错误通常发生在连接 MySQL 8.0 或更高版本的数据库时。其根本原因是客户端与服务器之间的认证机制不匹配,尤其是在未使用 SSL 加密连接的情况下。

🧐 错误原因分析

MySQL 8.0 为了增强安全性,默认采用了 caching_sha2_password 作为用户的认证插件。当客户端尝试连接时:

  1. 安全握手 :如果连接没有启用 SSL 加密(即 useSSL=false),客户端需要使用服务器的 RSA 公钥来加密密码,然后发送给服务器进行验证。
  2. 获取公钥:为了获取这个公钥,客户端会向服务器发起一个"公钥检索"请求。
  3. 默认禁止 :出于安全考虑(防止中间人攻击),JDBC 驱动等客户端默认是禁止自动检索公钥的。

因此,当你尝试用一个非 SSL 连接去连接一个使用 caching_sha2_password 认证的用户时,就会因为无法获取公钥而报错 Public Key Retrieval is not allowed

✅ 解决方案

以下是几种常见的解决方法,你可以根据自己的环境(开发、测试或生产)选择最合适的一种。

方案一:修改连接字符串(适用于开发/测试环境)

这是最快速直接的解决方法。在你的 JDBC 连接 URL 中,显式地添加两个参数:allowPublicKeyRetrieval=trueuseSSL=false

  • allowPublicKeyRetrieval=true: 允许客户端从服务器检索公钥。
  • useSSL=false: 明确禁用 SSL 连接。

配置示例:

  • JDBC URL:

    复制代码
    jdbc:mysql://localhost:3306/your_database?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
  • Spring Boot (application.properties):

    properties 复制代码
    spring.datasource.url=jdbc:mysql://localhost:3306/your_database?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
    spring.datasource.username=your_username
    spring.datasource.password=your_password
  • Spring Boot (application.yml):

    yaml 复制代码
    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/your_database?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
        username: your_username
        password: your_password

⚠️ 安全警告 :此方法会降低连接的安全性,因为它允许在不加密的信道上交换公钥。强烈建议仅在本地开发或可信的内部测试环境中使用

方案二:修改用户认证插件(兼容性方案)

将数据库用户的认证方式改回旧版的 mysql_native_password。这种方式不依赖 RSA 公钥进行密码加密,因此可以避免此问题。

你需要登录到 MySQL 数据库(可以使用命令行或其他已连接的客户端),然后执行以下 SQL 命令:

sql 复制代码
-- 将 'your_user' 和 'your_host' 替换为你的实际用户名和主机
-- 将 'your_password' 替换为你的新密码
ALTER USER 'your_user'@'your_host' IDENTIFIED WITH mysql_native_password BY 'your_password';
FLUSH PRIVILEGES;

这个方法兼容性很好,但放弃了 caching_sha2_password 带来的更强安全性,可以作为临时或兼容性方案。

方案三:配置 SSL 加密连接(生产环境推荐)

在生产环境中,最佳实践是启用 SSL/TLS 加密连接。这样,密码等敏感信息会在加密通道中传输,无需通过不安全的公钥检索方式。

你需要配置有效的 SSL 证书,并在连接字符串中设置相关参数:

  • useSSL=true: 启用 SSL。
  • requireSSL=true: 要求必须使用 SSL 连接。
  • verifyServerCertificate=true: 验证服务器证书的有效性。

配置示例:

复制代码
jdbc:mysql://localhost:3306/your_database?useSSL=true&requireSSL=true&verifyServerCertificate=true&...

这种方法安全性最高,符合生产环境的安全合规要求。

相关推荐
YOU OU4 小时前
Redis基础常识与命令
数据库·redis·缓存
腻害兔4 小时前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社5 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
萧瑟余晖6 小时前
JDK 26 新特性详解
java·开发语言
Database_Cool_6 小时前
OLTP 和 OLAP 区别详解:分析型数据库和事务型数据库怎么选(附阿里云 AnalyticDB MySQL 选型指南)
数据库·mysql·阿里云
爱写代码的阿森6 小时前
鸿蒙三方库 | harmony-utils之KvUtil键值型数据库操作详解
数据库·华为·harmonyos·鸿蒙·huawei
马优晨6 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
Database_Cool_7 小时前
单机 MySQL 迁移到分布式数据库方便吗?阿里云 PolarDB-X 100% MySQL 协议兼容零改造平滑迁移
数据库·分布式·mysql
姜太小白7 小时前
【MySQL】 索引优化实战:解决 WHERE 等值 + IS NULL 查询,TEXT 字段报错 1167 的完整指南
数据库·mysql