MySQL 8.0的Public Key Retrival错误,毫无规律可言怎么破?

2023-10-20 13:30

本文主要是介绍MySQL 8.0的Public Key Retrival错误,毫无规律可言怎么破?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

点击↑蓝字【DBAplus社群】并创建星标★

持续收获更多独家原创干货!

作者介绍

农行研发中心“数风云”团队一支朝气蓬勃、快速成长的技术团队,始终致力于农行大数据、数据库和云计算等领域的应用实践与技术创新,探索数据赋能,勇攀数据云巅,为企业数字化转型和金融科技发展不断贡献力量。

一、背景介绍

近期笔者所在部门在使用MySQL时,经常会出现如下错误,且这个错误并不会一直出现,属于某种偶发性的错误:

笔者所在部门的连接数据库的方法有JDBC、JDBCTemplate、C3P0连接池和Druid连接池等技术,在这些连接实现方法上笔者都观察到出现过上述的错误。该错误有一定的特性,就是偶尔会出现该错误,该错误并不会一直出现,该错误的出现没有明显的规律。而且笔者发现,底层使用JDBC连接驱动的情况下,无论上层是采用何种数据源实现技术,笔者的部门都发现会报上述错误。

针对上述错误,在笔者所在部门的软硬件环境下,笔者对MySQL为何会产生这个问题、这个问题产生的条件、MySQL官方文档对这个问题的阐述、如何有效避免与解决这个问题等方面在本文进行了详细的分析与解释。希望能够帮助到真正遇到这个问题的DBA与开发人员。

二、环境介绍

1、实验构架

笔者所在部门使用的MySQL版本为8.0.18版本,MySQL使用组复制技术保证高可用,即MySQL Group Replication(MGR)。笔者复现问题以及实验的架构如下图所示:

图2.1  实验所采用的构架

本测试使用的MySQL MGR集群搭建在虚拟机之上,虚拟机的详细硬件配置如下表所示:

表2.1  详细硬件配置

为了充分测试各种类型的连接数据库的方式在笔者所在部门使用的MySQL上的表现,笔者分别测试JDBC、JDBCTemplate、C3P0以及Druid方式连接数据库,参与测试的软件版本如下表所示:

表2.2  参与测试的软件版本

三、问题报错展示

在使用JDBC连接时,可能会出现“Public Key Retrieval is not allowed”的错误,从错误的Java堆栈信息中可以看出,该错误是在JDBC与MySQL建立Connection对象时出现的,该错误的错误堆栈如下图所示:

图3.1  JDBC错误堆栈

在使用C3P0连接池时,也会出现“Public Key Retrieval is not allowed”的错误,从错误的Java堆栈信息中可以看出,该错误仍是在JDBC与MySQL建立Connection对象时出现,该错误会导致C3P0连接池在初始化时失败,该错误的错误堆栈如下图所示:

图3.2  C3P0错误堆栈

在使用Druid连接池时,也会出现“Public Key Retrieval is not allowed”的错误,与C3P0连接池一样,会导致Druid连接池在初始化时失败,该错误的错误堆栈如下图所示:

图3.3  Druid错误堆栈

四、问题分析

笔者在查阅了网上关于“Public Key Retrieval is not allowed”错误的资料后,发现大多数网上关于该问题的博文对该问题的解释都存在一定的纰漏。首先需要明确的是出现该问题的时候,MySQL配置的密码认证插件为如下两种:

  • sha256_password

  • caching_sha2_password

值得注意的是,如果使用“mysql_native_password”密码认证插件,不会出现“Public Key Retrieval is not allowed”错误。MySQL配置的密码认证方式可以通过如下命令进行查看。

接着笔者来详细分析“Public Key Retrieval is not allowed”错误产生的原因。首先MySQL 8.0默认推荐使用“sha256_password”和“caching_sha2_password”这两种认证插件。只有较老的MySQL版本仍然会使用“mysql_native_password”。

根据MySQL提供的官方文档(https://dev.mysql.com/doc/refman/8.0/en/caching-sha2-pluggable-authentication.html),这两种插件都是使用SHA256算法来对密码进行保护。这些插件的具体执行流程如下:

  1. 检查客户端是否禁用SSL/TLS加密传输;

  2. 如果客户端未禁用SSL/TLS加密传输,则客户端在进行认证时的认证报文(传输用户名和密码的报文)是使用TLS进行传输的,两种插件认为认证报文传输安全,不进行任何其他操作;

  3. 如果客户端禁用SSL/TLS加密传输,则客户端在进行认证时的认证报文(传输用户名和密码的报文)是使用明文进行传输的,两种插件认为认证报文传输不安全,会单独对明文报文中的密码使用RSA加密方式进行加密。

1、启用SSL/TLS加密传输的客户端认证流程

如上述流程所述,当客户端未禁用SSL/TLS加密传输时,通过Wireshark等抓包工具可以观察到整个客户端与MySQL服务端交互的过程都被TLS协议加密保护了。如下图所示:

图4.1  启用TLS协议MySQL传输报文

虽然会产生登录的明文报文,但是该明文报文中的用户信息为空,真正的用户信息在TLS握手阶段后的密文中。如下图所示:

图4.2  启用TLS协议MySQL登录数据包详情

2、禁用SSL/TLS加密传输的客户端认证流程

如上述流程所述,当客户端禁用SSL/TLS加密传输时(比如JDBC连接串设置useSSL=false参数),用户的登录信息会在明文中进行传输,如下图所示:

图4.3  禁用TLS协议MySQL传输报文

明文传输密码存在安全问题,此时,两种插件会尝试使用RSA加密(RSA encryption)方法对明文报文中的密码部分进行加密,加密后的密码部分如下图所示:

图4.4  启用TLS协议MySQL登录数据包详情

五、解决方案

根据前面的分析,导致“Public Key Retrieval is not allowed”主要是由于当禁用SSL/TLS协议传输后,客户端会使用服务器的公钥进行传输,默认情况下客户端不会主动去找服务器拿公钥,此时就会出现上述错误。

经过查阅官方文档,出现Public Key Retrieval的场景可以概括为在禁用SSL/TLS协议传输切当前用户在服务器端没有登录缓存的情况下,客户端没有办法拿到服务器的公钥。具体的场景如下:

  1. 新建数据库用户,首次登录;

  2. 数据库的用户名、密码发生改变后登录;

  3. 服务器端调用FLUSH PRIVELEGES指令刷新服务器缓存。

针对上述错误,有如下的解决方案:

  1. 在条件允许的情况下,不要禁用SSL/TLS协议,即不要在CLI客户端使用--ssl-mode=disabled,或在JDBC连接串中加入useSSL=false;

  2. 如果必须禁用SSL/TLS协议,则可以尝试使用CLI客户端登录一次MySQL数据库制造登录缓存;

  3. 如果必须禁用SSL/TLS协议,则可以通过增加如下参数允许客户端获得服务器的公钥:

  • 在JDBC连接串中加入allowPublicKeyRetrieval=true参数;

  • 在CLI客户端连接时加入--get-server-public-key参数;

  • 在CLI客户端连接时加入--server-public-key-path=file_name参数,指定存放在本地的公钥文件。

这篇关于MySQL 8.0的Public Key Retrival错误,毫无规律可言怎么破?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/247409

相关文章

MySQL字符串转数值的方法全解析

《MySQL字符串转数值的方法全解析》在MySQL开发中,字符串与数值的转换是高频操作,本文从隐式转换原理、显式转换方法、典型场景案例、风险防控四个维度系统梳理,助您精准掌握这一核心技能,需要的朋友可... 目录一、隐式转换:自动但需警惕的&ld编程quo;双刃剑”二、显式转换:三大核心方法详解三、典型场景

MySQL中between and的基本用法、范围查询示例详解

《MySQL中betweenand的基本用法、范围查询示例详解》BETWEENAND操作符在MySQL中用于选择在两个值之间的数据,包括边界值,它支持数值和日期类型,示例展示了如何使用BETWEEN... 目录一、between and语法二、使用示例2.1、betwphpeen and数值查询2.2、be

MySQL快速复制一张表的四种核心方法(包括表结构和数据)

《MySQL快速复制一张表的四种核心方法(包括表结构和数据)》本文详细介绍了四种复制MySQL表(结构+数据)的方法,并对每种方法进行了对比分析,适用于不同场景和数据量的复制需求,特别是针对超大表(1... 目录一、mysql 复制表(结构+数据)的 4 种核心方法(面试结构化回答)方法 1:CREATE

SQL Server中行转列方法详细讲解

《SQLServer中行转列方法详细讲解》SQL行转列、列转行可以帮助我们更方便地处理数据,生成需要的报表和结果集,:本文主要介绍SQLServer中行转列方法的相关资料,需要的朋友可以参考下... 目录前言一、为什么需要行转列二、行转列的基本概念三、使用PIVOT运算符进行行转列1.创建示例数据表并插入数

SpringBoot项目整合Netty启动失败的常见错误总结

《SpringBoot项目整合Netty启动失败的常见错误总结》本文总结了SpringBoot集成Netty时常见的8类问题及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录一、端口冲突问题1. Tomcat与Netty端口冲突二、主线程被阻塞问题1. Netty启动阻

MySQL MHA集群详解(数据库高可用)

《MySQLMHA集群详解(数据库高可用)》MHA(MasterHighAvailability)是开源MySQL高可用管理工具,用于自动故障检测与转移,支持异步或半同步复制的MySQL主从架构,本... 目录mysql 高可用方案:MHA 详解与实战1. MHA 简介2. MHA 的组件组成(1)MHA

SpringBoot整合Kafka启动失败的常见错误问题总结(推荐)

《SpringBoot整合Kafka启动失败的常见错误问题总结(推荐)》本文总结了SpringBoot项目整合Kafka启动失败的常见错误,包括Kafka服务器连接问题、序列化配置错误、依赖配置问题、... 目录一、Kafka服务器连接问题1. Kafka服务器无法连接2. 开发环境与生产环境网络不通二、序

SQL 注入攻击(SQL Injection)原理、利用方式与防御策略深度解析

《SQL注入攻击(SQLInjection)原理、利用方式与防御策略深度解析》本文将从SQL注入的基本原理、攻击方式、常见利用手法,到企业级防御方案进行全面讲解,以帮助开发者和安全人员更系统地理解... 目录一、前言二、SQL 注入攻击的基本概念三、SQL 注入常见类型分析1. 基于错误回显的注入(Erro

MySQL基本表查询操作汇总之单表查询+多表操作大全

《MySQL基本表查询操作汇总之单表查询+多表操作大全》本文全面介绍了MySQL单表查询与多表操作的关键技术,包括基本语法、高级查询、表别名使用、多表连接及子查询等,并提供了丰富的实例,感兴趣的朋友跟... 目录一、单表查询整合(一)通用模版展示(二)举例说明(三)注意事项(四)Mapper简单举例简单查询

MySQL中的DELETE删除数据及注意事项

《MySQL中的DELETE删除数据及注意事项》MySQL的DELETE语句是数据库操作中不可或缺的一部分,通过合理使用索引、批量删除、避免全表删除、使用TRUNCATE、使用ORDERBY和LIMI... 目录1. 基本语法单表删除2. 高级用法使用子查询删除删除多表3. 性能优化策略使用索引批量删除避免