从源码分析 MySQL 身份验证插件的实现细节

最近在分析ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)这个报错的常见原因。

在分析的过程中,不可避免会涉及到 MySQL 身份验证的一些实现细节。

加之之前对这一块就有很多疑问,包括:

  1. 一个明文密码,是如何生成 mysql.user 表中的 authentication_string?
  2. 在进行身份验证时,客户端是否会直接发送明文密码给 MySQL 服务端?
  3. MySQL 8.0 为什么要将默认的身份认证插件调整为 caching_sha2_password,mysql_native_password 有什么问题嘛?

所以,就从代码层面对 MySQL 身份验证插件(主要是 mysql_native_password)的一些实现细节进行了分析。

本文主要包括以下几部分:

  1. 服务端是如何对明文密码进行加密的?
  2. 服务端是如何进行客户端身份验证的?
  3. 客户端是如何处理明文密码的?会直接发送明文密码给服务端么?
  4. 服务端是如何验证客户端密码是否正确的?
  5. 为什么 MySQL 8.0 要将默认的身份认证插件调整为 caching_sha2_password?

服务端是如何对明文密码进行加密的?