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&...

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

相关推荐
Web Security Loop16 分钟前
MAC卸载JDK环境
java·macos·jdk
NiceCloud喜云35 分钟前
腾讯云国际版云数据库选型:MySQL、Redis 怎么按业务架构来判断
数据库·mysql·腾讯云
ew4521844 分钟前
MySQL JOIN 关联语法、差异、标准用法、经典坑点汇总
数据库·mysql
Rain的Java大神之路1 小时前
线上接口负载满了如何解决
java·数据库·redis·后端·缓存·面试·架构
Nturmoils1 小时前
给运营导个 CSV,在 ksql 里用 \copy 就够了
数据库
ciqingloveless2 小时前
Oracle打开数据库加密
数据库·oracle
counting money2 小时前
Tomcat 专题:从基础架构到性能调优与 WebSocket 实战
java·websocket·tomcat
m0_462605222 小时前
大模型week02
数据库
DBA_G2 小时前
GBase 8a数据库集群多维度资源管控策略矩阵解析
数据库·oracle
xiaohaiAIgeo2 小时前
【2026年】HG/T 20656-2024化工暖通空调设计规范:新版标准的变化与影响
java·前端·javascript·科普知识