当前位置:首页 > 随笔 > 正文内容

MySQL 8.0 中 caching_sha2_password 认证插件的工作原理与应用

访客 随笔 2026年9月8日 2

引言

自 MySQL 8.0.4 版本起,默认身份验证插件由 mysql_native_password 更改为 caching_sha2_password。这一变更同时影响了 libmysqlclient 库,使其也采用 caching_sha2_password 作为默认的身份验证机制。

认证机制的演变

传统认证方式

在 MySQL 5.6/5.7 版本中,默认使用的密码插件是 mysql_native_password。此插件的主要特点是无需加密连接即可工作,验证速度非常快。然而,其安全性存在明显缺陷,因为它使用 SHA1 算法进行密码验证。美国国家标准与技术研究院(NIST)早已建议停止使用 SHA1 算法,因为该算法与 MD5 等哈希算法一样,存在被破解的风险。

实际上,从 MySQL 5.6 开始,就引入了更为安全的认证机制: sha256_password 认证插件。该插件采用加盐密码进行多轮 SHA256 哈希(通常执行数千轮哈希运算,大大增加了暴力破解的难度)。然而,这种安全性的提升是以性能为代价的——建立安全连接和执行多轮哈希加密会消耗较多时间,导致验证速度较慢。

新认证机制的诞生

为了兼顾安全性和性能,MySQL 在 8.0.3 版本中引入了 caching_sha2_password 认证插件,作为 sha256_password 的替代方案。新插件在保留原有安全特性的基础上进行了优化,有效解决了性能问题。同时,MySQL 官方也宣布将在未来版本中移除 sha256_password 插件,建议使用该插件进行身份验证的账户迁移至 caching_sha2_password

实际影响

由于默认身份验证机制的变更,许多用户在使用 MySQL 8.0 时遇到了连接问题。例如,使用旧版本客户端连接时可能会出现以下错误:

shell> mysql -uroot -p
ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be loaded

尽管网络上有许多教程建议将认证方式改回 mysql_native_password,但从安全角度考虑,对于需要公网访问的 MySQL 服务,建议继续使用 caching_sha2_password 作为认证插件。

认证机制详解

mysql_native_password 工作原理

mysql_native_password 作为 MySQL 5.6/5.7 的默认密码插件,支持挑战-响应(challenge-response)机制,这是一种快速的验证方式,无需在网络中传输实际密码,也不需要加密连接。

其工作流程如下:

  1. 客户端连接到 MySQL 实例时,首先从服务器获取一个 20 字节的随机数(称为 nonce)
  2. 对于用户密码,系统通过 SHA1(SHA1(password)) 进行两次哈希计算,结果存储在 mysql.user 表的 authentication_string 列中
  3. 密码哈希值未使用盐值(salt),相同密码会产生相同的哈希值

尽管这种方式在当时相对安全,但随着计算能力的提升,现在面临两种主要风险:SHA1 算法已变得容易被破解,且相同密码会产生相同哈希值,增加了彩虹表攻击的可能性。

caching_sha2_password 工作原理

caching_sha2_password 认证机制在多个方面进行了改进:

  • 存储在 authentication_string 中的哈希值为加盐后的值,即使用户密码相同,不同用户的哈希值也不同
  • 哈希算法升级为更安全的 SHA256 算法
  • 哈希计算轮数从原来的两次提升至 5000 次,增加了暴力破解的难度
  • 使用 TLS 加密连接或 RSA 密钥对进行密码传输

通信过程解析

1. 快速认证模式(有缓存时)

当密码的哈希值已缓存在服务器内存中时,验证过程基于 SHA256 的挑战-响应机制,流程如下:

  1. 客户端发起连接请求
  2. 服务器生成并发送一个 20 字节的随机数据(nonce)给客户端
  3. 客户端使用公式 XOR(SHA256(password), SHA256(SHA256(SHA256(password)), nonce)) 生成 Scramble 并发送给服务器
  4. 服务器检查用户名和 SHA256(SHA256(user_password)) 是否存在于内存缓存中,若存在则验证通过
  5. 服务器发送 fast_auth_success 包给客户端
  6. 服务器发送 OK 包,进入命令阶段

2. 完整认证模式(无缓存时)

当服务器内存中没有密码哈希缓存时,caching_sha2_password 需要使用安全连接进行密码交换:

  1. 客户端发起连接请求
  2. 服务器生成并发送一个 20 字节的随机数据(nonce)给客户端
  3. 客户端使用公式 XOR(SHA256(password), SHA256(SHA256(SHA256(password)), nonce)) 生成 Scramble 并发送给服务器
  4. 服务器检查用户名和 SHA256(SHA256(user_password)) 是否存在于内存缓存中,若不存在则发送 perform_full_authentication 包
  5. 客户端收到 perform_full_authentication 包后,根据连接安全情况进行处理:
    • 如果已建立安全连接(如 TLS),则直接发送明文密码
    • 否则,请求获取服务器公钥或使用指定公钥文件,用公钥和 nonce 加密密码后发送
  6. 服务器使用私钥解密密码(如适用),通过 SHA256 算法计算哈希值并验证
  7. 验证通过后,服务器发送 OK 包,进入命令阶段

RSA 加密通信过程

在非安全连接中,caching_sha2_password 使用 RSA 非对称加密算法保护密码传输:

  1. 服务器生成 RSA 密钥对,并将公钥发送给客户端
  2. 客户端使用服务器公钥对密码进行加密
  3. 客户端将加密后的密码发送给服务器
  4. 服务器使用对应的私钥解密密码

由于只有服务器拥有私钥,即使加密数据被截获,攻击者也无法解密获取原始密码。

实施注意事项

默认身份验证插件的变更意味着在 MySQL 8.0.4 之后创建的所有新用户将默认使用 caching_sha2_password 作为身份验证插件。可以通过以下查询查看用户认证插件:

mysql> SELECT USER,PLUGIN FROM mysql.`user` ;
+------------------+-----------------------+
| USER             | PLUGIN                |
+------------------+-----------------------+
| root             | caching_sha2_password |
| mysql.infoschema | caching_sha2_password |
| mysql.session    | caching_sha2_password |
| mysql.sys        | caching_sha2_password |
+------------------+-----------------------+

对于使用 caching_sha2_password 插件的客户端,连接服务器时密码传输方式取决于连接是否安全:

  • 安全连接:包括使用 TLS 加密的 TCP 连接、Unix 套接字文件和共享内存连接。密码以明文格式发送,但由于连接本身是加密的,密码不会被窃听。
  • 非安全连接:包括未使用 TLS 加密的 TCP 连接和命名管道连接。系统使用 RSA 密钥对对密码进行加密,防止密码被截取。服务器接收到加密密码后,使用私钥解密。加密过程中使用随机字符串,防止重放攻击。

在 MySQL 8.0.3 以上版本中,RSA 密钥对的生成和交换过程是自动完成的。

主从复制环境中的配置

MySQL 8.0.4 添加了对复制场景中 RSA 加密的支持。如果用于复制的用户使用了 caching_sha2_password 身份验证插件,且未启用安全连接,MySQL 将使用 RSA 密钥对进行密码交换。

对于传统复制,可以通过以下参数启用基于 caching_sha2_password 的 RSA 密钥交换:

# 指定 RSA 公钥路径
CHANGE MASTER TO MASTER_PUBLIC_KEY_PATH = "/path/to/public_key.pem";

# 从服务端获取 RSA 公钥
CHANGE MASTER TO GET_MASTER_PUBLIC_KEY = 1;

对于组复制(Group Replication),可以通过以下参数配置:

# 指定 RSA 公钥路径
–-group-replication-recovery-public-key-path="/path/to/public_key.pem"

# 从服务端获取 RSA 公钥
–-group-replication-recovery-get-public-key=1

数据库升级考虑

当数据库升级到 MySQL 8.0.4 或更高版本时,需要注意以下几点:

  • 升级前创建的用户,其身份认证插件不会自动更改
  • 升级后创建的用户默认使用 caching_sha2_password 身份验证插件
  • 可以通过 --default-authentication-plugin 参数手动指定认证插件
  • 旧版本客户端仍可连接升级前创建的用户账户

建议升级 libmysqlclient 到 MySQL 8.0.4 或更高版本,以支持新的身份验证插件。同时,出于安全考虑,建议逐步将用户账户迁移至 caching_sha2_password 认证方式。

标签: MySQL

相关文章

可以按小时收费的VPS

很多 VPS 提供商都支持 按小时计费(hourly billing),想短期试用 / 临时搭建节点、测试网络、短期项目等场景非常合适。下面是当前最主流且靠谱的按小时 VPS 选项,分别按不同需求场景整理: 1. Vultr(全球节点,包括日本) 按小时计费 可选机房:东京 / 大阪 / 洛杉矶 / 法兰克福 / 伦敦 … 支持 PayPal(部分情况),但更常用信用卡/PayPal+卡价格参考$...

在 iPhone 上下载国外App

地区/国家限制App Store 会根据 Apple ID 的国家或地区限制应用下载。如果你的 Apple ID 绑定的是中国大陆,就可能无法下载 OpenAI 官方的 ChatGPT 应用,因为它在大陆 App Store 不上架。解决办法:换成美国、加拿大、香港等地区的 Apple ID。或者在现有 Apple ID 上更改地区。注册一个国外 Apple ID(推荐)比如注册 美国区 Appl...

Node.js 中的异步编程:回调与 Promise

Node.js 是一个基于 JavaScript 构建的单线程、非阻塞运行环境,它通过异步编程机制来高效处理多个操作。在执行如文件读取、API 请求或数据库查询等任务时,Node.js 不会等待这些操作完成,而是使用回调函数和 Promise 来避免阻塞主线程。 回调方式实现异步 那么当异步操作完成后,Node.js 如何知道接下来要做什么呢?这就要用到 回调函数(callback)。 回调本质上...

Selenium自动化测试入门指南

Selenium自动化测试入门指南

什么是自动化测试? 自动化测试是指利用软件工具自动执行测试用例,模拟用户操作,如打开网页、点击链接、输入文本等,并验证结果是否符合预期。 其主要优点包括: 大幅减少人工成本 测试速度快 可以在非工作时间运行 支持持续集成和交付 然而,它也存在一些局限性,例如开发成本较高、不适合快速变化的项目、依赖稳定的UI界面等。 自动化测试的应用条件 适合引入自动化测试的情况包括: 手动测试耗时且需要大量...

MariaDB Galera集群故障快速恢复指南

OpenStack控制节点采用三节点MariaDB Galera集群架构。当数据库集群因故障重启时,有时会出现Galera集群无法正常启动的问题。虽然有多种方法可以恢复数据库服务,但如何实现快速启动同时确保数据完整性呢? 通过分析日志发现,MariaDB Galera集群节点宕机时会在日志中输出以下信息: [Note] WSREP: 新集群视图:全局状态: 874d8e7e-5980-11e8-8...

Android 中 EventBus 的通信机制与实现原理深度解析

EventBus 核心设计思想 EventBus 是一个基于观察者模式的事件总线框架,广泛应用于 Android 平台以实现组件解耦。它通过中心化的消息分发机制,使不同层级、不同线程的对象能够以"发布-订阅"方式通信,避免了传统接口回调或广播带来的强依赖问题。 核心角色说明 事件(Event):任意 Java 对象,作为数据载体,如网络状态变更通知、用户登录信息等。 发布者(Publi...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。