Public Key Retrieval is not allowed

这个错误通常在使用 JDBC 驱动连接 MySQL 数据库时出现,特别是在启用 SSL 加密或使用 caching_sha2_password 认证插件的场景中。下面是详细解析和解决方案:

一、错误原因

MySQL 8.0 及以上版本默认使用 caching_sha2_password 认证插件,该插件在某些情况下需要从服务器获取公钥以完成加密连接:

  1. SSL 连接:需要公钥进行证书验证。
  2. 密码加密:客户端需要公钥加密密码。

当 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 指定本地公钥文件路径,避免动态检索。

四、安全注意事项

  1. 生产环境建议:
    • 使用 publicKeyPath 预配置公钥,而非动态检索。
    • 启用 useSSL=true 和 verifyServerCertificate=true 确保连接安全。
  2. 开发环境权衡:
    • 若安全风险可控,可临时启用 allowPublicKeyRetrieval=true

五、验证方法

  1. 检查认证插件:
    SELECT user, host, plugin 
    FROM mysql.user 
    WHERE user = 'your_username';
    
     
  2. 查看连接日志:
    在 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" 错误,并根据实际场景平衡安全性与便利性

posted on 2025-05-15 11:30  数据与人文  阅读(11238)  评论(0)    收藏  举报