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

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

相关推荐
2301_800954995 分钟前
关系型数据库与非关系型数据库详解
数据库·nosql
崖边看雾6 分钟前
MySQL——SQL 经典练习题:学生选课成绩查询(附详细注释)
大数据·数据库·sql·mysql
众壹新能源科技7 分钟前
经营口径与运维口径不一致时,发电量报表怎么对账
运维·数据库·人工智能
jyOverQ32 分钟前
MySQL 索引为什么能加快查询?B+Tree 到底是什么?
数据库·mysql
hfywmsj41 分钟前
广州餐饮铺位招租的选址架构:流量入口与成本函数分析
java·大数据·jvm·广州餐饮铺位招租
爪哇岛国人43 分钟前
原来我一直理解错了:实现接口真的必须实现所有方法吗?
java
天天进步20151 小时前
Pixelle-Video 源码解析 #17:TTS 语音生成:Edge-TTS、Index-TTS 如何接入?
前端·数据库
鸽芷咕1 小时前
异构数据同步,凭什么敢说数据不丢?——拆解金仓KFS的全周期一致性校验
数据库
海浪仙人掌1 小时前
账龄分析的定义是什么?账龄分析有什么作用?
数据库
ACP广源盛139246256731 小时前
M6/M5 Pro Mac mini 端侧 AI 落地@ACP#IX6024 PCIe2.0 交换芯片在轻量化 AI 服务中的机会与应用场景
大数据·数据库·人工智能·嵌入式硬件·macos·开源