Public Key Retrieval is not allowed
这个错误通常在使用 JDBC 驱动连接 MySQL 数据库时出现,特别是在启用 SSL 加密或使用 caching_sha2_password 认证插件的场景中。下面是详细解析和解决方案:
一、错误原因
MySQL 8.0 及以上版本默认使用
caching_sha2_password 认证插件,该插件在某些情况下需要从服务器获取公钥以完成加密连接:- SSL 连接:需要公钥进行证书验证。
- 密码加密:客户端需要公钥加密密码。
当 JDBC 驱动尝试自动检索公钥时,如果连接 URL 中未明确允许,就会抛出此错误。
二、解决方案
1. 在连接 URL 中允许公钥检索
在 JDBC URL 中添加参数
allowPublicKeyRetrieval=true:String url = "jdbc:mysql://localhost:3306/yourdb?" +
"allowPublicKeyRetrieval=true&" +
"useSSL=true&" +
"verifyServerCertificate=true";
Connection conn = DriverManager.getConnection(url, "username", "password");
2. 修改 MySQL 用户认证方式
将用户认证方式改为
mysql_native_password,避免公钥检索:ALTER USER 'your_username'@'localhost'
IDENTIFIED WITH mysql_native_password BY 'your_password';
FLUSH PRIVILEGES;
3. 预先生成并配置公钥
手动获取服务器公钥并配置到客户端:
String url = "jdbc:mysql://localhost:3306/yourdb?" +
"publicKeyPath=/path/to/public_key.pem&" +
"useSSL=true";
- 生成公钥:
mysql -u root -p -e "SHOW CREATE USER 'your_username';" > public_key.pem
三、参数详解
| 参数名 | 作用 |
|---|---|
allowPublicKeyRetrieval |
允许驱动从服务器检索公钥(默认 false)。启用后可能存在安全风险(中间人攻击)。 |
useSSL |
强制使用 SSL 连接(默认 false)。 |
verifyServerCertificate |
验证服务器证书(默认 true)。 |
publicKeyPath |
指定本地公钥文件路径,避免动态检索。 |
四、安全注意事项
-
生产环境建议:
- 使用
publicKeyPath预配置公钥,而非动态检索。 - 启用
useSSL=true和verifyServerCertificate=true确保连接安全。
- 使用
-
开发环境权衡:
- 若安全风险可控,可临时启用
allowPublicKeyRetrieval=true。
- 若安全风险可控,可临时启用
五、验证方法
-
检查认证插件:
SELECT user, host, plugin FROM mysql.user WHERE user = 'your_username'; -
查看连接日志:
在 JDBC URL 中添加loggerLevel=FINE查看详细连接过程:String url = "jdbc:mysql://localhost:3306/yourdb?" + "allowPublicKeyRetrieval=true&" + "loggerLevel=FINE";
六、版本兼容性
- MySQL 5.7:默认使用
mysql_native_password,一般无需此配置。 - MySQL 8.0+:默认使用
caching_sha2_password,需显式处理公钥。 - JDBC 驱动:建议使用 8.0.23 及以上版本,修复了部分公钥检索问题。
通过上述方法,可有效解决 "Public Key Retrieval is not allowed" 错误,并根据实际场景平衡安全性与便利性
浙公网安备 33010602011771号