扩展 MySQL 8.0  / 第 4 章 MySQL 插件 API  / 4.4 编写插件  / 4.4.9 编写认证插件  /  6.4.1.4 缓存 SHA-2 可插入认证

6.4.1.4 缓存 SHA-2 可插入认证

MySQL 提供了两个身份验证插件,它们为用户帐户密码实现 SHA-256 散列:

  • sha256_password:实现基本的 SHA-256 身份验证。

  • caching_sha2_password:实现 SHA-256 身份验证(如sha256_password),但在服务器端使用缓存以获得更好的性能,并具有更广泛适用性的附加功能。(在 MySQL 5.7 中,caching_sha2_password仅在客户端实现,如本节后面所述。)

本节介绍缓存 SHA-2 身份验证插件,从 MySQL 5.7.23 开始可用。有关原始基本(非缓存)插件的信息,请参阅 第 6.4.1.5 节,“SHA-256 可插入身份验证”

重要的

在 MySQL 5.7 中,默认的身份验证插件是 mysql_native_password. 从 MySQL 8.0 开始,默认身份验证插件更改为 caching_sha2_password. 为了使 MySQL 5.7 客户端能够使用通过 进行身份验证的帐户连接到 8.0 及更高版本的服务器 caching_sha2_password,MySQL 5.7 客户端库和客户端程序支持 caching_sha2_password客户端身份验证插件。这提高了 MySQL 5.7 客户端连接能力相对于 MySQL 8.0 和更高版本服务器的兼容性,尽管默认身份验证插件存在差异。

与 MySQL 8.0 相比,将 MySQL 5.7 中的支持限制caching_sha2_password为客户端库中的客户端插件具有以下含义:

此外,不支持 MySQL 5.7 副本使用通过 caching_sha2_password. 这将涉及源复制到版本号低于源版本的副本,而源通常复制到版本等于或高于源版本的副本。

重要的

要使用通过插件进行身份验证的帐户连接到 MySQL 8.0 或更高版本的服务器 caching_sha2_password,您必须使用安全连接或支持使用 RSA 密钥对进行密码交换的未加密连接,如本节后面所述。无论哪种方式,该 caching_sha2_password插件都使用 MySQL 的加密功能。请参阅 第 6.3 节,“使用加密连接”

笔记

在名称sha256_password中, sha256指的是插件用于加密的 256 位摘要长度。在名称 caching_sha2_password中,sha2 更泛指 SHA-2 类加密算法,其中 256 位加密就是一个实例。后一种名称选择为将来扩展可能的摘要长度留下了空间,而无需更改插件名称。

caching_sha2_password与以下插件相比, 该插件具有以下优点sha256_password

  • 在服务器端,内存中的缓存可以让之前连接过的用户在再次连接时更快地重新进行身份验证。(此服务器端行为仅在 MySQL 8.0 及更高版本中实现。)

  • 为使用 Unix 套接字文件和共享内存协议的客户端连接提供支持。

下表显示了客户端的插件名称。

表 6.10 用于 SHA-2 身份验证的插件和库名称

插件或文件 插件或文件名
客户端插件 caching_sha2_password
库文件 无(内置插件)

以下部分提供特定于缓存 SHA-2 可插入身份验证的安装和使用信息:

有关 MySQL 中可插入身份验证的一般信息,请参阅第 6.2.13 节,“可插入身份验证”

安装 SHA-2 可插拔身份验证

在 MySQL 5.7 中,该caching_sha2_password 插件以客户端形式存在。客户端插件内置于libmysqlclient客户端库中,可用于链接到 libmysqlclient.

使用 SHA-2 可插拔身份验证

在 MySQL 5.7 中,客户端插件允许使用通过服务器端插件caching_sha2_password 进行身份验证的帐户连接到 MySQL 8.0 或更高版本的服务器 。caching_sha2_password这里的讨论假设 'sha2user'@'localhost'在 MySQL 8.0 或更高版本的服务器上存在名为 的帐户。例如,以下语句创建这样一个帐户,其中 password是所需的帐户密码:

CREATE USER 'sha2user'@'localhost'
IDENTIFIED WITH caching_sha2_password BY 'password';

caching_sha2_password支持安全传输连接。 caching_sha2_password如果满足以下条件,还支持在未加密连接上使用 RSA 加密密码交换:

  • MySQL 5.7 客户端库和客户端程序是使用 OpenSSL 而不是 yaSSL 编译的。 caching_sha2_password适用于使用任一包编译的发行版,但 RSA 支持需要 OpenSSL。

    笔记

    仅在 MySQL 5.7.28 之前,可以使用 yaSSL 作为 OpenSSL 的替代方案来编译 MySQL。从 MySQL 5.7.28 开始,删除了对 yaSSL 的支持,所有 MySQL 构建都使用 OpenSSL。

  • 您希望连接的 MySQL 8.0 或更高版本的服务器被配置为支持 RSA(使用本节后面给出的 RSA 配置过程)。

RSA 支持具有以下特征,其中与服务器端相关的所有方面都需要 MySQL 8.0 或更高版本的服务器:

  • 在服务器端,两个系统变量命名 RSA 私钥和公钥对文件: caching_sha2_password_private_key_pathcaching_sha2_password_public_key_path. 如果要使用的密钥文件的名称与系统变量默认值不同,则数据库管理员必须在服务器启动时设置这些变量。

  • 服务器使用 caching_sha2_password_auto_generate_rsa_keys 系统变量来确定是否自动生成 RSA 密钥对文件。请参阅 第 6.3.3 节,“创建 SSL 和 RSA 证书和密钥”

  • 状态变量显示身份验证插件 使用 的 Caching_sha2_password_rsa_public_key RSA 公钥值。caching_sha2_password

  • 拥有 RSA 公钥的客户端可以在连接过程中与服务器进行基于 RSA 密钥对的密码交换,如后所述。

  • 对于使用基于 RSA 密钥对的密码交换进行身份验证的帐户的连接, caching_sha2_password默认情况下服务器不会将 RSA 公钥发送给客户端。客户端可以使用所需公钥的客户端副本,或从服务器请求公钥。

    使用受信任的公钥本地副本使客户端能够避免客户端/服务器协议中的往返,并且比从服务器请求公钥更安全。另一方面,从服务器请求公钥更方便(它不需要管理客户端文件)并且在安全网络环境中可能是可以接受的。

    在所有情况下,如果提供了指定有效公钥文件的选项,则它优先于从服务器请求公钥的选项。

对于使用该 caching_sha2_password插件的客户端,在连接到 MySQL 8.0 或更高版本的服务器时,密码永远不会以明文形式公开。密码传输的方式取决于是否使用安全连接或 RSA 加密:

  • 如果连接是安全的,则不需要 RSA 密钥对,也不会使用它。这适用于使用 TLS 加密的 TCP 连接,以及 Unix 套接字文件和共享内存连接。密码以明文形式发送,但不能被窥探,因为连接是安全的。

  • 如果连接不安全,则使用 RSA 密钥对。这适用于未使用 TLS 加密的 TCP 连接和命名管道连接。RSA 仅用于客户端和服务器之间的密码交换,以防止密码窥探。当服务器收到加密的密码时,它会对其进行解密。在加密中使用加扰来防止重复攻击。

  • 如果未使用安全连接且 RSA 加密不可用,则连接尝试会失败,因为如果不以明文形式公开密码,则无法发送密码。

如前所述,仅当使用 OpenSSL 编译 MySQL 5.7 时,RSA 密码加密才可用。对于使用 yaSSL 编译的 MySQL 5.7 发行版的客户端来说,要使用 SHA-2 密码,客户端 必须使用加密连接来访问服务器。请参阅 第 6.3.1 节,“配置 MySQL 以使用加密连接”

假设 MySQL 5.7 已使用 OpenSSL 编译,使用以下过程可以在客户端连接过程中使用 RSA 密钥对进行密码交换。

重要的

此过程中与服务器配置相关的方面必须在您希望使用 MySQL 5.7 客户端连接到的 MySQL 8.0 或更高版本的服务器上完成, 而不是在您的 MySQL 5.7 服务器上完成。

  1. 使用第 6.3.3 节“创建 SSL 和 RSA 证书和密钥” 中的说明创建 RSA 私钥和公钥对文件。

  2. 如果私钥文件和公钥文件位于数据目录中,并命名为 private_key.pemand public_key.pemcaching_sha2_password_private_key_pathcaching_sha2_password_public_key_path 系统变量的默认值),服务器会在启动时自动使用它们。

    否则,要显式命名密钥文件,请将系统变量设置为服务器选项文件中的密钥文件名。如果文件位于服务器数据目录中,则无需指定它们的完整路径名:

    [mysqld]
    caching_sha2_password_private_key_path=myprivkey.pem
    caching_sha2_password_public_key_path=mypubkey.pem

    如果密钥文件不在数据目录中,或者要使其在系统变量值中的位置明确,请使用完整路径名:

    [mysqld]
    caching_sha2_password_private_key_path=/usr/local/mysql/myprivkey.pem
    caching_sha2_password_public_key_path=/usr/local/mysql/mypubkey.pem
  3. 重新启动服务器,然后连接到它并检查 Caching_sha2_password_rsa_public_key 状态变量值。实际值与此处显示的不同,但应该是非空的:

    mysql> SHOW STATUS LIKE 'Caching_sha2_password_rsa_public_key'\G
    *************************** 1. row ***************************
    Variable_name: Caching_sha2_password_rsa_public_key
            Value: -----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDO9nRUDd+KvSZgY7cNBZMNpwX6
    MvE1PbJFXO7u18nJ9lwc99Du/E7lw6CVXw7VKrXPeHbVQUzGyUNkf45Nz/ckaaJa
    aLgJOBCIDmNVnyU54OT/1lcs2xiyfaDMe8fCJ64ZwTnKbY2gkt1IMjUAB5Ogd5kJ
    g8aV7EtKwyhHb0c30QIDAQAB
    -----END PUBLIC KEY-----

    如果该值为空,则服务器发现密钥文件存在问题。检查错误日志以获取诊断信息。

使用 RSA 密钥文件配置服务器后,使用插件进行身份验证的帐户可以 caching_sha2_password选择使用这些密钥文件连接到服务器。如前所述,此类帐户可以使用安全连接(在这种情况下不使用 RSA)或使用 RSA 执行密码交换的未加密连接。假设使用未加密的连接。例如:

$> mysql --ssl-mode=DISABLED -u sha2user -p
Enter password: password

对于 的这次连接尝试sha2user,服务器确定它 caching_sha2_password是适当的身份验证插件并调用它(因为那是当时指定的插件CREATE USER )。该插件发现连接未加密,因此要求使用 RSA 加密传输密码。但是服务端并没有将公钥发送给客户端,而客户端又没有提供公钥,所以无法加密密码,连接失败:

ERROR 2061 (HY000): Authentication plugin 'caching_sha2_password'
reported error: Authentication requires secure connection.

要从服务器请求 RSA 公钥,请指定 --get-server-public-key选项:

$> mysql --ssl-mode=DISABLED -u sha2user -p --get-server-public-key
Enter password: password

在这种情况下,服务器将 RSA 公钥发送给客户端,客户端使用它来加密密码并将结果返回给服务器。插件使用服务器端的RSA私钥解密密码,根据密码是否正确接受或拒绝连接。

或者,如果客户端有一个文件包含服务器所需的 RSA 公钥的本地副本,它可以使用以下 --server-public-key-path选项指定该文件:

$> mysql --ssl-mode=DISABLED -u sha2user -p --server-public-key-path=file_name
Enter password: password

在这种情况下,客户端使用公钥对密码进行加密,并将结果返回给服务器。插件使用服务器端的RSA私钥解密密码,根据密码是否正确接受或拒绝连接。

选项命名的文件中 的公钥值应与 系统变量--server-public-key-path命名的服务器端文件中的密钥值相同 。caching_sha2_password_public_key_path如果密钥文件包含有效的公钥值但该值不正确,则会发生拒绝访问错误。如果密钥文件不包含有效的公钥,则客户端程序无法使用它。

客户端用户可以通过两种方式获取RSA公钥:

  • 数据库管理员可以提供公钥文件的副本。

  • 可以通过其他方式连接到服务器的客户端用户可以使用SHOW STATUS LIKE 'Caching_sha2_password_rsa_public_key'语句并将返回的键值保存在文件中。

SHA-2 可插拔身份验证的缓存操作

在服务器端,该 caching_sha2_password插件使用内存缓存来更快地验证之前连接过的客户端。对于仅支持 caching_sha2_password客户端插件的 MySQL 5.7,此服务器端缓存因此发生在您使用 MySQL 5.7 客户端连接到的 MySQL 8.0 或更高版本的服务器上。有关缓存操作的信息,请参阅 MySQL 8.0 参考手册中的SHA-2 可插入身份验证的缓存操作