news 2026/9/24 19:41:06

DBeaver连MySQL8.0的PublicKeyRetrieval报错解决

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DBeaver连MySQL8.0的PublicKeyRetrieval报错解决

前两天准备把一台开发机的 MySQL 从 5.7 升到 8.0,升级完顺手打开 DBeaver 想连上去看下数据表结构,结果“连接测试”直接甩给我一行红字:Public Key Retrieval is not allowed。紧接着就是一大段英文堆栈。第一次遇到这个报错的人,第一反应多半是“我密码是不是写错了”,然后反复重输密码,折腾十分钟发现根本没用。其实这个报错跟密码一毛钱关系都没有,是 MySQL 8.0 的默认认证机制变了,而 DBeaver 用的 JDBC 驱动出于安全考虑,默认不允许自动获取服务器公钥,两边一冲突就报错。

这个问题在 DBeaver 连 MySQL 8.0 的场景里几乎人人都会撞上一次,网上答案零零散散,有人让你改驱动属性,有人让你改 MySQL 用户,还有人直接让你换驱动版本,新手往往不知道该听谁的。这篇文章我把三种可行方案从头到尾捋一遍,包括背后的原理、具体操作步骤、各自的适用场景,以及改完之后仍然连不上的排查思路。不管你是 DBA、后端开发、测试还是刚接触数据库的新手,照着做完基本都能解决。

1. 先搞懂报错原因:MySQL 8.0 的认证机制变化

1.1 报错现场:什么情况下会触发

先说说我遇到这个问题的现场。我的环境是:DBeaver Community 版(具体版本号已经记不清,但肯定是 21.x 以上的版本),MySQL 8.0.28,JDBC 驱动是 DBeaver 自带的 mysql-connector-java。连接方式是最普通不过的 TCP/IP,用的用户是 root,host 是 localhost。

点击“测试连接”后,DBeaver 弹出的错误信息大致如下:

Public Key Retrieval is not allowed

点开详情还能看到类似这样一段:

java.sql.SQLException: Public Key Retrieval is not allowed at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129) ...

如果你和我一样用的是 5.x 版本的 MySQL,这个错误是绝对不会出现的。从 MySQL 8.0 开始,默认的认证插件从 mysql_native_password 换成了 caching_sha2_password,这一换,连带着 JDBC 客户端的连接行为也变了。

另外说一句,这个问题不只在 DBeaver 里出现。只要是基于 JDBC 的客户端,比如 IntelliJ IDEA 自带的 Database 工具、SQuirreL SQL、DataGrip 等,都有可能遇到同样的报错。区别只是部分工具版本比较新,已经在默认参数里帮你开了公钥检索,所以不报错;而 DBeaver 的默认配置比较保守,就把这个错误暴露出来了。

1.2 caching_sha2_password 和公钥检索到底是怎么回事

要理解这个报错,得先知道 MySQL 8.0 在认证环节做了什么改动。

MySQL 5.7 及更早的版本默认使用 mysql_native_password 插件,密码校验方式是 SHA1 加盐哈希,客户端在认证时直接把这个哈希结果发给服务器,整个过程不需要额外的密钥交换。这种方式简单粗暴,但安全性已经跟不上时代,尤其是碰撞攻击和暴力破解的成本越来越低。

MySQL 8.0 引入了 caching_sha2_password 插件并把它设为默认。它同样基于 SHA256,但密码不会明文传输,而是先通过服务器的 RSA 公钥加密,再发送到服务器端解密校验。问题就出在这个“RSA 公钥”上。

如果客户端和服务器之间没有走 SSL/TLS 加密连接,那么 caching_sha2_password 在认证阶段会经历一个“获取公钥”的步骤。这个公钥的获取有两种方式:一是服务器在握手过程中主动把公钥发给客户端,二是客户端主动向服务器发起请求,索取公钥。

而 MySQL 的 JDBC 驱动(mysql-connector-java)在连接参数里有一个开关叫 allowPublicKeyRetrieval,控制的就是“是否允许客户端主动向服务器索取公钥”。这个参数默认是 false。当它为 false,连接又没启用 SSL,服务器也不会在握手时自动下发公钥,于是驱动直接抛出 Public Key Retrieval is not allowed 来阻止连接继续。

一句话概括:不是密码错了,是认证过程中需要拿一把公钥来加密密码,但 JDBC 驱动默认不让你去拿。

1.3 为什么 JDBC 驱动要关闭这个开关

你可能会问,既然服务器可以提供公钥,那 JDBC 驱动默认允许不就行了,何必搞这么一出?

这里涉及中间人攻击的考量。如果客户端在建立连接时,不加验证地去获取服务器公钥,那攻击者可以在网络链路上假装自己是目标服务器,提前给客户端一个自己的公钥。客户端用这把假公钥加密密码,攻击者在另一边截获后用私钥解密,密码就泄露了。

所以 JDBC 驱动把这个选项设计成默认关闭,属于“默认最安全”的取舍。你要明确告诉驱动“这台服务器我是信的”,或者干脆换一条带 SSL 加密的通道,它才肯放开公钥检索。

明白了这层逻辑,后续几种解法就很好理解了:要么手动打开公钥检索的开关,要么让服务器端改用旧版认证方式绕开 RSA 公钥交换,要么直接走 SSL 加密连接。

2. 最快解法:在 DBeaver 里打开公钥检索

2.1 图形界面操作步骤

如果你是开发环境自查,或者公司内网连接测试环境,最省事的方法就是在 DBeaver 连接设置里把 allowPublicKeyRetrieval 参数打开。

注意,不同版本的 DBeaver 界面布局有细微差异,但大体路径一致。我的操作步骤是这样的:

  1. 在 DBeaver 左侧“数据库导航器”里,找到你配置的那个 MySQL 连接。
  2. 右键点击连接名称,选择“编辑连接”。
  3. 在弹出的连接设置窗口里,找到“驱动属性”标签页(英文版是 Driver properties)。
  4. 在属性列表里找到 allowPublicKeyRetrieval,如果看不到,可以直接在上方的搜索框里输入 public key 快速定位。
  5. 把这一项的值从默认的 false 改成 true。
  6. 点击“确定”保存,再重新点“测试连接”。

如果你用的 DBeaver 版本较新,在“连接设置”页面的“SSL”标签页里,也可能直接有一个勾选项叫“Allow public key retrieval”,勾上它等价于修改 allowPublicKeyRetrieval=true,效果完全相同。

改完之后再次测试连接,一般就能顺利通过。我在本机实测下来,只要这一步改了,连接基本秒过,不再弹任何报错。

2.2 手动编辑 JDBC URL 的方式

如果你没法通过图形界面改,或者你用的是其他基于 JDBC 的客户端,那就直接编辑连接 URL,在末尾追加参数也行。

以 DBeaver 为例,在“编辑连接”窗口的“主要”标签页里,通常能看到“JDBC URL”这个字段。如果界面上是隐藏的,可以点“编辑驱动设置”或者直接切换到手动配置模式。URL 最终的样子类似:

jdbc:mysql://127.0.0.1:3306/your_database?allowPublicKeyRetrieval=true&useSSL=false

这里我额外加了一个 useSSL=false,原因是如果不明确指定 SSL 行为,驱动可能默认尝试协商 SSL,某些场景下会引来额外报错或者告警。不过要注意,useSSL=false 和 allowPublicKeyRetrieval=true 一起使用,相当于明确告诉驱动:我不走加密通道,但允许我去服务器拿公钥。在可信内网环境没问题,但在公网环境请谨慎,后面第四部分我会详细说 SSL 的事。

2.3 这个操作背后的代价和注意点

allowPublicKeyRetrieval=true 不是万能的,它有一个安全隐患值得你记住:开启后,客户端会无条件接受服务器返回的公钥并用来加密密码。如果连接链路上存在恶意节点,它有机会冒充服务器,诱导客户端用它的公钥加密密码,从而窃取密码内容。

所以我的建议是:

  • 本机开发、公司内网、测试环境,放心用。
  • 生产环境或者跨公网连接,尽量别开,应该优先考虑 SSL 或修改服务器端认证方式。
  • 如果你在一个多人共用的网络环境(比如咖啡馆 WiFi、酒店网络)里远程连数据库,开这个参数等于把密码明文送给潜在攻击者去解密。

DBeaver 这个参数是保存在连接配置里的,换一台电脑、换一个工作空间之后需要重新设置。旧版本里修改后记得点右下角的“应用”按钮,否则可能没保存成功。

3. 另一条路:把 MySQL 用户认证插件改回旧版

3.1 查看和修改认证插件

对于不想动客户端参数、希望在服务器端一次性解决的人,可以把目标用户的认证插件改回 mysql_native_password。这样客户端不需要走 RSA 公钥交换,而是用旧版 SHA1 校验方式完成认证,问题也就消失了。

这个操作需要先能通过其他方式登录 MySQL,比如命令行客户端。步骤如下:

先用命令行登录 MySQL:

mysql -u root -p

登录后查看当前各用户的认证插件:

SELECT user, host, plugin FROM mysql.user;

你会看到类似这样的结果:

+------------------+-----------+-----------------------+ | user | host | plugin | +------------------+-----------+-----------------------+ | root | localhost | caching_sha2_password | | mysql.sys | localhost | caching_sha2_password | | deer | % | caching_sha2_password | +------------------+-----------+-----------------------+

接着把需要修改的用户改为 mysql_native_password:

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码'; FLUSH PRIVILEGES;

如果你用的是远程连接,主机名部分是 ip 或 %,那就要改成对应的 host,比如:

ALTER USER 'app_user'@'%' IDENTIFIED WITH mysql_native_password BY '你的密码';

改完再用 DBeaver 连接,你会发现不需要勾选 allowPublicKeyRetrieval 也能连上。

3.2 一个越来越明显的坑:新版 MySQL 已经移除旧插件

不过这里我必须提醒一句,mysql_native_password 在 MySQL 8.0 里能用,但不代表在 8.0 的所有小版本里都能一直用下去。从 8.0.34 开始,MySQL 在用户认证相关的日志里会对 mysql_native_password 给出弃用警告。更关键的是,从 MySQL 9.0 开始,这个插件已经被彻底移除了。

如果哪一天你升级到 MySQL 9.x,再想用这招就没戏了。到时候服务器端根本不会加载 mysql_native_password 插件,ALTER USER 直接报错。

所以我的判断是:这条路短期可用,适合现有业务系统里已经大量使用 mysql_native_password、一时半会儿改不动客户端的团队。但如果你的数据库是从零开始搭建,或者你还在评估长期方案,我建议不要为了省事把所有用户都改成这个旧插件。迟早都要迁回 caching_sha2_password,不如现在就适应它,用方案一或者方案四来解决问题。

3.3 两种方案的适用场景对比

这里直接列一个对比表,方便你根据实际情况做决定。

对比项方案一:allowPublicKeyRetrieval=true方案二:改回 mysql_native_password
操作位置客户端 DBeaver 连接配置服务器端 MySQL 用户设置
改动范围每次连接单独配置全局生效,所有客户端都会受影响
安全隐患有中间人攻击风险旧版认证算法安全性相对更低
兼容性适用于 MySQL 5.7 到 9.x 全系列不适用 MySQL 9.0+
适用场景开发环境个人电脑快速连库遗留系统统一迁移,客户端版本受限的场景
长期可维护性高,参数本身没有弃用计划低,MySQL 官方已明确淘汰路线

我个人处理线上问题时,90% 的情况都直接用方案一,让开发同学在 DBeaver 里勾一个参数就完事,不用动服务器。只有遇到那种“服务器端必须强制使用 caching_sha2_password”的安全合规要求时,才去考虑改服务器或者做 SSL。

4. 更稳妥的姿势:直接上 SSL

4.1 连接参数里启用 SSL

回到本质问题:caching_sha2_password 之所以需要“公钥检索”,是因为数据不走加密通道,才需要在认证环节单独做 RSA 公钥加密。如果你直接把客户端和服务器之间的连接改成 SSL/TLS 加密通道,认证过程就不再需要额外的公钥检索,因为整个密码传输过程已经被 TLS 保护了。

在 DBeaver 里启用 SSL,路径如下:

  1. 右键连接,选择“编辑连接”。
  2. 切换到“SSL”标签页。
  3. 勾选“使用 SSL”(Use SSL)。
  4. 如果服务器没有配置受信任的 CA 证书,可以勾选“跳过主机名验证”或“信任服务器证书”,具体看你服务器的证书情况。
  5. 保存后重新测试连接。

如果通过 JDBC URL 配置,则在连接串里加:

jdbc:mysql://127.0.0.1:3306/your_database?useSSL=true&requireSSL=true

有些版本还支持 verifyServerCertificate=false,表示不强制校验服务器证书链。

4.2 SSL 方案的使用场景和注意事项

SSL 方案最大的优势是安全性和兼容性都高。它既不需要关闭驱动侧的安全开关,也不用把用户认证插件退回旧版,是 MySQL 官方推荐的正向路径。但也有麻烦的地方:服务器必须配置好 SSL 证书,尤其是自签名证书,需要导入客户端信任库,否则 DBeaver 会报证书校验失败。

实际操作中,大多数开发者并不想为了一次本地连库去折腾证书。MySQL 8.0 在初始化数据目录时,会自动生成一套自签名 SSL 证书,文件通常在 MySQL 的 data 目录下,比如 ca.pem、server-cert.pem、server-key.pem。DBeaver 里如果勾选 SSL,有时只要把 CA 证书路径指到 ca.pem 就能过;证书位置不对时要先查一下:

SHOW VARIABLES LIKE 'ssl_ca'; SHOW VARIABLES LIKE 'ssl_cert';

MySQL 服务器如果完全没开启 SSL 支持,可以在配置文件 my.cnf 里加上:

[mysqld] ssl-ca=/path/to/ca.pem ssl-cert=/path/to/server-cert.pem ssl-key=/path/to/server-key.pem

然后重启 MySQL 服务。

我的建议是:如果你是图省事,那 SSL 不是首选,方案一绝对最快。但如果你所在的公司对数据库连接有合规要求,或者你需要在公网远程连接数据库,那别犹豫,直接上 SSL,别为了一时方便把密码暴露在不安全的环境里。

5. 踩坑实录:改完还报错的排查思路

5.1 常见的连坐报错

有时候按网上的教程改了参数,结果还是连不上,这时候问题可能不只是公钥检索这么简单了。我把实际排查中遇到过的情况列出来:

报错一:Unable to load authentication plugin 'caching_sha2_password'

这种一般是驱动版本太老。老版本的 mysql-connector-java(比如 5.1.x)不认识 caching_sha2_password 新插件,直接就罢工了。解决办法是升级驱动,换成 mysql-connector-java 8.0.x 或更高版本。DBeaver 社区版自带驱动通常已经是 8.x,但如果你的 DBeaver 比较老,或者手动指定过旧驱动,就会触发这个问题。

报错二:Access denied for user 'root'@'localhost'

这个才是真正的密码错误或用户权限问题。如果确认密码没错,可以检查一下用户的 host 是否匹配,比如你的客户端从 192.168.1.100 连过来,但 MySQL 里只授权了 root@localhost,那怎么连都会拒绝。

报错三:Communications link failure

网络层面的问题,跟认证无关。检查 IP 写没写对、端口是不是 3306、服务器防火墙有没有放行、MySQL 的 bind-address 是不是只允许本机连接。如果 bind-address=127.0.0.1,远程是连不进来的。

5.2 排查步骤速查表

整理了一个排查清单,遇到类似问题按顺序过一遍:

现象排查项解决方向
Public Key Retrieval is not allowedDBeaver 驱动属性 allowPublicKeyRetrieval设为 true 或走 SSL
Public Key Retrieval is not allowedJDBC URL 是否手动指定了参数确认参数拼写、大小写正确
Unable to load authentication pluginJDBC 驱动版本升级到 mysql-connector-java 8.0+
Access denied for user用户名、密码、host 是否匹配检查 mysql.user 授权记录
Communications link failure网络连通性、端口、防火墙从客户端 telnet 测试端口是否通
SSL 证书校验失败CA 证书路径、是否跳过验证确认证书文件路径,或临时关闭验证

5.3 另外几个容易被忽略的隐藏问题

有时候参数改对了,但 DBeaver 还是报错,原因可能是连接名下面保存了旧连接驱动信息。DBeaver 对每个连接会缓存驱动配置,修改“驱动属性”后一定要点“确定”而不是直接点窗口右上角关闭,否则修改内容不生效。

还有一个常见问题是多个 MySQL 连接共用同一个驱动实例,修改一个连接的属性后,其他同驱动连接可能也会受影响,或者反过来,你改了 A 连接的 driver properties,但 B 连接加载的还是旧缓存。

另外,DBeaver 会在连接失败时把错误详情折叠起来,默认只显示一句话。如果想看完整堆栈,点开错误信息下面的“详细信息”或“查看日志”,有时候真实原因和公钥检索无关,比如服务器返回的时区信息异常(The server time zone value ... is unrecognized),也会导致连接中断。这种问题一般需要给 URL 加 serverTimezone=Asia/Shanghai 或改成 useSSL=false&serverTimezone=UTC。

还有一种很少被提及的情况:同一台机器上装了多个 MySQL 实例,一个 5.7 一个 8.0,端口分别是 3306 和 3307,DBeaver 连接配置里端口写错了,连到老实例上,行为自然不同。这种问题用最笨的办法排查:命令行mysql -h127.0.0.1 -P端口 -uroot -p先连一次,看命令行时候能不能过。

我在实际工作中最常用的一招是:先在命令行用 mysql 客户端连同一个库,确认用户名密码和网络都没问题,再去排查 DBeaver 侧配置。这样至少能区分是服务器端问题还是客户端问题,避免毫无头绪地乱改参数。

最后再分享一个小技巧:如果你在 DBeaver 里勾完 allowPublicKeyRetrieval 之后仍然报同样的错,不妨把 DBeaver 彻底退出再重开一次,让它重新加载驱动配置。有些版本对运行中修改的连接属性支持不好,重开之后反而好了。我遇到过不止一次这种情况,虽然看起来有点笨,但实测有效。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 19:40:35

DQN源码实战:在Atari Breakout上复现训练与避坑指南

简介:面向游戏AI与深度强化学习入门者,这份基于DQN的Atari Breakout智能体设计项目,将理论、代码与文档整合为可直接运行的完整方案,适合计算机、人工智能、自动化等专业学生作为毕设、课设或项目初期演示使用。内容从深度学习与强…

作者头像 李华
网站建设 2026/9/24 19:38:51

Kafka面试核心考点与实战排查全解析

"427的Kafka面经汇总"也不知道是哪位同行把自己的面试复盘整理成了一份叫"427的Kafka面经汇总"的资料,最近在好几个技术社群里都看到有人转,内容确实有货。我在中间件这行干了也有年头了,Kafka从0.8时代一直用到现在的3.…

作者头像 李华
网站建设 2026/9/24 19:38:18

H3C SecPath V5防火墙日常维护三大核心:巡检、备份与升级

1. 为什么H3C SecPath V5防火墙的“日常维护”不是可选项,而是运行生命线我第一次接手一台在线运行三年的SecPath F1000-A30(V5平台)时,它正卡在“配置同步失败”的告警里——表面看只是Web界面刷新慢,但后台日志里每分…

作者头像 李华
网站建设 2026/9/24 19:37:50

Trae CN完整配置教程:从环境搭建到项目联动

Trae CN最近应该是AI编程工具里被讨论最多的一款。很多人下载完Trae CN装上就完事,结果过两天就抱怨“AI听不懂我说话”“终端找不到命令”,问题基本都出在安装后的配置环节。我前后在公司电脑和家里电脑各折腾了一遍,把JDK、Python、Node.js…

作者头像 李华
网站建设 2026/9/24 19:37:48

Trae CN安装配置实战:从环境准备到AI编程工具的高效使用

Trae CN 是字节跳动推出的 AI 编程工具,一款基于 VSCode 内核深度定制的集成开发环境(IDE)。它最核心的价值,是把大模型的能力直接塞进了编辑器里——你可以在侧边栏对话生成代码、选中报错让 AI 解释修复、甚至用自然语言描述需求…

作者头像 李华
网站建设 2026/9/24 19:36:37

acore-db-app:Python封装库,让AzerothCore数据库操作化繁为简

维护AzerothCore服务端的朋友应该都有过这种经历:开发到后期,各种数据修复、批量任务、跨库同步的需求接踵而来,每天不是在写SQL,就是在写连接数据库的Python脚本。我自己的痛点是,pymysql裸用起来倒是不难&#xff0c…

作者头像 李华