MySQL 提供了两个身份验证插件,它们为用户帐户密码实现 SHA-256 哈希
caching_sha2_password
: 实现 SHA-256 身份验证(类似于sha256_password
),但在服务器端使用缓存以获得更好的性能,并具有其他功能以更广泛地适用。sha256_password
: 实现基本的 SHA-256 身份验证。此插件已弃用,可能会被移除,请勿使用此身份验证插件。
本节介绍缓存 SHA-2 身份验证插件。有关原始基本(非缓存)已弃用插件的信息,请参见 第 8.4.1.2 节,“SHA-256 可插拔身份验证”.
在 MySQL 9.0 中,caching_sha2_password
是默认的身份验证插件;mysql_native_password
不再可用。有关此更改对服务器操作以及服务器与客户端和连接器的兼容性的影响的信息,请参见 caching_sha2_password 作为首选身份验证插件.
要使用使用 caching_sha2_password
插件进行身份验证的帐户连接到服务器,您必须使用安全连接或支持使用 RSA 密钥对交换密码的未加密连接,如本节后面所述。无论哪种方式,caching_sha2_password
插件都使用 MySQL 的加密功能。参见 第 8.3 节,“使用加密连接”.
在名称 sha256_password
中,“sha256” 指的是插件用于加密的 256 位摘要长度。在名称 caching_sha2_password
中,“sha2” 更普遍地指的是 SHA-2 类加密算法,其中 256 位加密是其中一个实例。后一种名称选择为将来可能的摘要长度扩展保留了空间,而无需更改插件名称。
与 sha256_password
相比,caching_sha2_password
插件具有以下优点
在服务器端,内存中缓存使以前连接过的用户在再次连接时能够更快地重新验证。
基于 RSA 的密码交换在与 MySQL 链接的 SSL 库无关的情况下可用。
支持使用 Unix 套接字文件和共享内存协议的客户端连接。
下表显示了服务器端和客户端的插件名称。
表 8.15 SHA-2 身份验证的插件和库名称
插件或文件 | 插件或文件名 |
---|---|
服务器端插件 | caching_sha2_password |
客户端插件 | caching_sha2_password |
库文件 | 无(插件内置) |
以下部分提供了特定于缓存 SHA-2 可插拔身份验证的安装和使用信息
有关 MySQL 中可插拔身份验证的一般信息,请参见 第 8.2.17 节,“可插拔身份验证”.
caching_sha2_password
插件以服务器和客户端形式存在
服务器端插件内置于服务器中,无需显式加载,也不能通过卸载来禁用。
客户端插件内置于
libmysqlclient
客户端库中,可用于链接到libmysqlclient
的任何程序。
服务器端插件使用 sha2_cache_cleaner
审计插件作为辅助程序来执行密码缓存管理。与 caching_sha2_password
一样,sha2_cache_cleaner
是内置的,无需安装。
要设置使用 caching_sha2_password
插件进行 SHA-256 密码哈希的帐户,请使用以下语句,其中 password
是所需的帐户密码
CREATE USER 'sha2user'@'localhost'
IDENTIFIED WITH caching_sha2_password BY 'password';
服务器将 caching_sha2_password
插件分配给帐户,并使用它使用 SHA-256 对密码进行加密,并将这些值存储在 mysql.user
系统表中的 plugin
和 authentication_string
列中。
上述说明不假设 caching_sha2_password
是默认的身份验证插件。如果 caching_sha2_password
是默认的身份验证插件,则可以使用更简单的 CREATE USER
语法
CREATE USER 'sha2user'@'localhost' IDENTIFIED BY 'password';
默认插件由 authentication_policy
系统变量的值确定;默认情况下使用 caching_sha2_password
。
要使用其他插件,必须使用 IDENTIFIED WITH
指定它。例如,要指定已弃用的 sha256_password
插件,请使用以下语句
CREATE USER 'nativeuser'@'localhost'
IDENTIFIED WITH sha256_password BY 'password';
caching_sha2_password
支持通过安全传输进行连接。如果您遵循本节后面给出的 RSA 配置过程,它还支持使用 RSA 通过未加密连接进行加密密码交换。RSA 支持具有以下特征
在服务器端,两个系统变量指定 RSA 私钥和公钥对文件:
caching_sha2_password_private_key_path
和caching_sha2_password_public_key_path
。如果要使用的密钥文件具有与系统变量默认值不同的名称,则数据库管理员必须在服务器启动时设置这些变量。服务器使用
caching_sha2_password_auto_generate_rsa_keys
系统变量来确定是否自动生成 RSA 密钥对文件。请参阅 第 8.3.3 节,“创建 SSL 和 RSA 证书和密钥”。Caching_sha2_password_rsa_public_key
状态变量显示caching_sha2_password
身份验证插件使用的 RSA 公钥值。拥有 RSA 公钥的客户端可以在连接过程中与服务器执行基于 RSA 密钥对的密码交换,如后所述。
对于使用
caching_sha2_password
和基于 RSA 密钥对的密码交换进行身份验证的帐户的连接,服务器默认情况下不会将 RSA 公钥发送到客户端。客户端可以使用 RSA 公钥的客户端副本,或者从服务器请求 RSA 公钥。使用公钥的受信任本地副本可以使客户端避免在客户端/服务器协议中的往返,并且比从服务器请求公钥更安全。另一方面,从服务器请求公钥更加方便(它不需要管理客户端文件),并且在安全网络环境中可能是可以接受的。
对于命令行客户端,使用
--server-public-key-path
选项指定 RSA 公钥文件。使用--get-server-public-key
选项从服务器请求 RSA 公钥。以下程序支持这两个选项:mysql、mysqlsh、mysqladmin、mysqlbinlog、mysqlcheck、mysqldump、mysqlimport、mysqlshow、mysqlslap、mysqltest.对于使用 C API 的程序,调用
mysql_options()
通过传递MYSQL_SERVER_PUBLIC_KEY
选项和文件名称来指定 RSA 公钥文件,或者通过传递MYSQL_OPT_GET_SERVER_PUBLIC_KEY
选项来从服务器请求 RSA 公钥。对于副本,使用
CHANGE REPLICATION SOURCE TO
语句,使用SOURCE_PUBLIC_KEY_PATH
选项指定 RSA 公钥文件,或者使用GET_SOURCE_PUBLIC_KEY
选项从源请求 RSA 公钥。对于组复制,group_replication_recovery_public_key_path
和group_replication_recovery_get_public_key
系统变量具有相同的用途。
在所有情况下,如果提供选项来指定有效的 RSA 公钥文件,则它优先于从服务器请求 RSA 公钥的选项。
对于使用 caching_sha2_password
插件的客户端,密码在连接到服务器时永远不会以明文形式显示。密码传输方式取决于是否使用安全连接或 RSA 加密
如果连接是安全的,则 RSA 密钥对是不必要的,不会使用。这适用于使用 TLS 加密的 TCP 连接,以及 Unix 套接字文件和共享内存连接。密码以明文形式发送,但由于连接是安全的,因此无法被窃取。
如果连接不安全,则使用 RSA 密钥对。这适用于不使用 TLS 加密的 TCP 连接和命名管道连接。RSA 仅用于客户端和服务器之间的密码交换,以防止密码窃取。当服务器收到加密密码时,它会对其进行解密。在加密中使用混淆来防止重复攻击。
要启用在客户端连接过程中使用 RSA 密钥对进行密码交换,请使用以下过程
使用 第 8.3.3 节,“创建 SSL 和 RSA 证书和密钥” 中的说明创建 RSA 私钥和公钥对文件。
如果私钥和公钥文件位于数据目录中,并且名为
private_key.pem
和public_key.pem
(caching_sha2_password_private_key_path
和caching_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
如果要更改密码生成过程中
caching_sha2_password
使用的哈希轮数,请设置caching_sha2_password_digest_rounds
系统变量。例如[mysqld] caching_sha2_password_digest_rounds=10000
重新启动服务器,然后连接到它并检查
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 公钥值,但该值不正确,则会发生访问被拒绝错误。如果密钥文件不包含有效的 RSA 公钥,则客户端程序无法使用它。
客户端用户可以通过两种方式获取 RSA 公钥
数据库管理员可以提供公钥文件的副本。
可以以其他方式连接到服务器的客户端用户可以使用
SHOW STATUS LIKE 'Caching_sha2_password_rsa_public_key'
语句并将返回的密钥值保存在文件中。
在服务器端,caching_sha2_password
插件使用内存中的缓存来更快地对以前连接过的客户端进行身份验证。条目由帐户名/密码哈希对组成。缓存的工作原理如下
当客户端连接时,
caching_sha2_password
检查客户端和密码是否与某些缓存条目匹配。如果是,则身份验证成功。如果没有匹配的缓存条目,该插件将尝试根据
mysql.user
系统表中的凭据验证客户端。如果成功,caching_sha2_password
会将客户端的条目添加到哈希中。否则,身份验证失败,连接被拒绝。
这样,当客户端第一次连接时,会针对 mysql.user
系统表进行身份验证。当客户端随后连接时,会针对缓存进行更快的身份验证。
除了添加条目之外的密码缓存操作由 sha2_cache_cleaner
审核插件处理,该插件代表 caching_sha2_password
执行这些操作
它会清除任何重命名或删除的帐户的缓存条目,或任何更改了凭据或身份验证插件的帐户的缓存条目。
当执行
FLUSH PRIVILEGES
语句时,它会清空缓存。它会在服务器关闭时清空缓存。(这意味着缓存不会在服务器重启之间持久化。)
缓存清除操作会影响后续客户端连接的身份验证要求。对于每个用户帐户,在执行以下任何操作后,用户的第一个客户端连接必须使用安全连接(使用 TLS 凭据通过 TCP 建立、使用 Unix 套接字文件或共享内存)或基于 RSA 密钥对的密码交换
帐户创建后。
帐户密码更改后。
在执行
RENAME USER
操作后。在执行
FLUSH PRIVILEGES
操作后。
FLUSH PRIVILEGES
会清除整个缓存,并影响所有使用 caching_sha2_password
插件的帐户。其他操作会清除特定的缓存条目,并且只影响参与操作的帐户。
用户成功身份验证后,帐户将被写入缓存,后续连接不需要安全连接或 RSA 密钥对,直到发生影响帐户的另一个缓存清除事件。(当可以使用缓存时,服务器使用挑战-响应机制,该机制不会使用明文密码传输,也不需要安全连接。)