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

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

相关推荐
谢慧琼2 分钟前
免费版收银系统支持多账号同时登录吗?
mysql
深盾科技_Virbox4 分钟前
Virbox Protector 从何而来:深盾科技的软件保护演进
运维·数据库·科技
只会写代码6 分钟前
一套开箱即用实体反射Lambda链式工具,彻底告别原生反射样板代码
java·程序员·源码
AI人工智能+电脑小能手7 分钟前
【大白话说Java面试题 第151题】【06_Spring篇】第11题:说一下 Spring Bean 的生命周期?
java·开发语言·后端·spring·面试
骑士雄师13 分钟前
java面试题:jvm ,mybatis
java·jvm·mybatis
rebibabo15 分钟前
Java基础(24) | MySQL 原理与优化:事务、存储引擎、索引与锁
mysql··存储引擎·explain·视图·最左前缀·事务acid
广州浮点FLOATLIC19 分钟前
Creo 许可证利用率怎么优化:制造企业该先看共享规则,还是先看模块占用结构
java·开发语言
2601_9624408430 分钟前
计算机毕业设计之jsp教室管理系统
java·开发语言·笔记·分布式·算法·课程设计·推荐算法
带刺的坐椅2 小时前
用 ChatModel 构建 LLM 驱动的 Java 应用
java·ai·llm·solon·rag·chatmodel
Flynt4 小时前
Room 3.0 包名重构 + KMP 迁移:我把项目升级踩了个遍
android·数据库·kotlin