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=true 和 useSSL=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&...

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

相关推荐
starrocks_stella10 分钟前
EMR Serverless StarRocks Object Table:用 SQL 连接 OSS 文件与多模态 AI
数据库
这个DBA有点耶19 分钟前
以为自增ID只是有空洞?聊聊双主架构下无声的“数据覆盖”
数据库·mysql·dba
陈布衣1 小时前
MySQL(1)_MySQL 5.7.21 Linux 安装笔记
linux·笔记·mysql
nice_lcj5201 小时前
ThreadLocal 入门:它是怎么隔离数据的、为什么会导致内存泄漏
java·开发语言·后端·面试·并发编程·内存泄漏·threadlocal
钱栈up1 小时前
内网全断,怎么核实高炉和烧结系统的数据库对接信息
数据库
秋天的怀念_David1 小时前
算法一千零一夜 · 第二十六夜 协议的母语
java·spring boot·算法
灿飞1 小时前
Kotlin与Java虚拟机八:控制流与 when:卫语句、上下文相关解析与穷尽性
java·kotlin
weavecodes1 小时前
双层缓存与权限实时生效:织码在线教育系统的 Caffeine + Redis 设计
数据库
bksczm2 小时前
InnoDB 页结构详解:页类型、页头页尾、数据行与页目录
数据库·mysql
文丑颜不良啊2 小时前
LeetCode2021~2040题目解析
java·leetcode