缓存SHA-2可插入身份验证
MySQL提供了两个身份验证插件,用于对用户帐户密码实施SHA-256哈希:
sha256_password
:实现基本的SHA-256身份验证。caching_sha2_password
:实现SHA-256身份验证(如sha256_password
),但是在服务器端使用缓存以获得更好的性能,并具有其他功能以提高适用性。
本节介绍了缓存SHA-2身份验证插件。有关原始基本(非缓存)插件的信息,请参见“ SHA-256可插拔身份验证”。
重要在MySQL 8.0中,
caching_sha2_password
是默认的身份验证插件,而不是mysql_native_password
。有关此更改对服务器操作的影响以及服务器与客户端和连接器的兼容性的信息,请参阅 caching_sha2_password作为“首选身份验证插件”。
重要要使用通过
caching_sha2_password
插件进行身份验证的帐户连接到服务器,必须使用支持使用RSA密钥对进行密码交换的安全连接或未加密连接,如本节稍后所述。无论哪种方式,该caching_sha2_password
插件都使用MySQL的加密功能。请参见“使用加密的连接”。
注意在名称中
sha256_password
,“ sha256 ”是指插件用于加密的256位摘要长度。在名称中caching_sha2_password
,“ sha2 ”更笼统地指SHA-2类加密算法,其中256位加密是其中的一个实例。后一种名称选择为将来扩展可能的摘要长度留出了空间,而无需更改插件名称。
该caching_sha2_password
插件有这些优势,相比于sha256_password
:
- 在服务器端,内存中的高速缓存使先前连接的用户在再次连接时可以更快地重新进行身份验证。
- 不管与MySQL链接的SSL库如何,都可以使用基于RSA的密码交换。
- 提供了对使用Unix套接字文件和共享内存协议的客户端连接的支持。
下表显示了服务器端和客户端上的插件名称。
表6.13 SHA-2身份验证的插件和库名称
插件或文件 | 插件或文件名 |
---|---|
服务器端插件 | caching_sha2_password |
客户端插件 | caching_sha2_password |
库文件 | 无(内置插件) |
以下各节提供了特定于缓存SHA-2可插拔身份验证的安装和使用信息:
- 安装SHA-2可插入身份验证
- 使用SHA-2可插入身份验证
- SHA-2可插入身份验证的缓存操作
有关MySQL中的可插入身份验证的一般信息,
安装SHA-2可插入身份验证
该caching_sha2_password
插件以服务器和客户端形式存在:
- 服务器端插件内置于服务器中,无需显式加载,也无法通过卸载禁用。
- 客户端插件内置在
libmysqlclient
客户端库中,可用于与链接的任何程序libmysqlclient
。
服务器端插件将sha2_cache_cleaner
审计插件用作帮助程序来执行密码缓存管理。sha2_cache_cleaner
,如caching_sha2_password
内置,无需安装。
使用SHA-2可插入身份验证
要设置使用caching_sha2_password
插件进行SHA-256密码哈希处理的帐户,请使用以下语句,其中password
所需的帐户密码为:
CREATE USER 'sha2user'@'localhost'IDENTIFIED WITH caching_sha2_passwordBY 'password';
服务器将caching_sha2_password
插件分配给该帐户,并使用它通过SHA-256加密密码,并将这些值存储在系统表的plugin
和 uthentication_string
列中mysql.user
。
前面的说明不假定这caching_sha2_password
是默认的身份验证插件。如果caching_sha2_password
是默认的身份验证插件,CREATE USER
则可以使用更简单的语法。
要在默认身份验证插件设置为的情况下启动服务器caching_sha2_password
,请将这些行放在服务器选项文件中:
[mysqld] default_authentication_plugin=caching_sha2_password
这导致该caching_sha2_password
插件默认情况下用于新帐户。结果,无需显式命名插件即可创建帐户并设置其密码:
CREATE USER 'sha2user'@'localhost'IDENTIFIED BY 'password';
设置default_authentication_plugin
为的另一个结果caching_sha2_password
是,要使用其他插件创建帐户,必须显式指定该插件。例如,要使用mysql_native_password
插件,请使用以下语句:
CREATE USER 'nativeuser'@'localhost'IDENTIFIED WITH mysql_native_passwordBY '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密钥对文件。请参见“创建SSL和RSA证书和密钥”。 - 该
Caching_sha2_password_rsa_public_key
状态变量显示由使用的RSA公钥值caching_sha2_password
认证插件。 - 拥有RSA公钥的客户端可以在连接过程中与服务器执行基于RSA密钥对的密码交换,如稍后所述。
对于通过身份验证进行帐户的连接
caching_sha2_password
以及基于RSA密钥对的密码交换,服务器默认不会将RSA公钥发送给客户端。客户端可以使用所需公用密钥的客户端副本,也可以从服务器请求公用密钥。使用公钥的受信任本地副本可以使客户端避免客户端/服务器协议中的往返,并且比从服务器请求公钥更安全。另一方面,从服务器请求公用密钥更为方便(它不需要管理客户端文件),并且在安全的网络环境中可以接受。
- 对于命令行客户端,使用
--server-public-key-path
选项指定RSA公钥文件。使用该--get-server-public-key
选项可从服务器请求公钥。以下程序支持两个选项:mysql,mysqlsh,mysqladmin,mysqlbinlog,mysqlcheck,mysqldump,mysqlimport,mysqlpump,mysqlshow,mysqlslap,mysqltest,mysql_upgrade。 - 对于使用C API的程序,
mysql_options()
通过传递MYSQL_SERVER_PUBLIC_KEY
选项和文件名来调用以指定RSA公钥文件,或者通过传递MYSQL_OPT_GET_SERVER_PUBLIC_KEY
选项来向服务器请求公钥。 - 对于复制从属,请使用
CHANGE MASTER TO
带有MASTER_PUBLIC_KEY_PATH
选项的语句指定RSA公钥文件,或者GET_MASTER_PUBLIC_KEY
从主服务器请求公钥的选项。对于组复制,group_replication_recovery_public_key_path
和group_replication_recovery_get_public_key
系统变量具有相同的用途。
在所有情况下,如果给出了用于指定有效公钥文件的选项,则它优先于从服务器请求公钥的选项。
- 对于命令行客户端,使用
对于使用该caching_sha2_password
插件的客户端,连接到服务器时,密码永远不会显示为明文。密码传输的方式取决于是否使用安全连接或RSA加密:
- 如果连接是安全的,则无需使用RSA密钥对。这适用于使用TLS的加密TCP连接以及Unix套接字文件和共享内存连接。密码以明文形式发送,但由于连接安全,因此无法监听。
- 如果连接不安全,则使用RSA密钥对。这适用于没有TLS和命名管道连接的未加密TCP连接。RSA仅用于客户端和服务器之间的密码交换,以防止密码监听。服务器收到加密的密码后,便对其进行解密。加密中使用加扰来防止重复攻击。
要在客户端连接过程中启用使用RSA密钥对进行密码交换,请使用以下过程:
- 使用“创建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_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进行密码交换的未加密连接。假设使用未加密的连接。例如:
shell>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
选项:
shell>mysql --ssl-mode=DISABLED -u sha2user -p --get-server-public-key Enter password: password
在这种情况下,服务器将RSA公钥发送给客户端,后者使用它来加密密码并将结果返回给服务器。插件使用服务器端的RSA私钥解密密码,并根据密码是否正确来接受或拒绝连接。
或者,如果客户端的文件包含服务器所需的RSA公钥的本地副本,则可以使用以下--server-public-key-path
选项指定文件:
shell>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.user
系统表中的凭据来验证客户端。如果成功,caching_sha2_password
则将客户端的条目添加到哈希中。否则,身份验证将失败并且连接将被拒绝。
这样,当客户端首次连接时,将针对mysql.user
系统表进行身份验证。当客户端随后连接时,将针对缓存进行更快的身份验证。
除了添加条目以外的密码缓存操作由sha2_cache_cleaner
审核插件处理,该审核插件代表caching_sha2_password
:
- 它将清除所有重命名或删除的帐户或更改了凭据或身份验证插件的帐户的缓存条目。
FLUSH PRIVILEGES
执行该语句时,它将清空缓存。- 它在服务器关闭时清空缓存。(这意味着缓存在服务器重新启动后不是持久的。)
缓存清除操作会影响后续客户端连接的身份验证要求。对于每个用户帐户,在执行以下任何操作之后,该用户的第一个客户端连接必须使用安全连接(使用TLS凭证,Unix套接字文件或共享内存的TCP进行安全连接)或基于RSA密钥对的密码交换:
- 创建帐户后。
- 更改帐户密码后。
- 之后
RENAME USER
为该帐户。 - 之后
FLUSH PRIVILEGES
。
FLUSH PRIVILEGES
清除整个缓存并影响使用该caching_sha2_password
插件的所有帐户。其他操作将清除特定的缓存条目,并且仅影响属于该操作的帐户。
一旦用户成功进行身份验证,该帐户便被输入到缓存中,随后的连接不需要安全连接或RSA密钥对,直到发生另一个影响该帐户的缓存清除事件。(当可以使用缓存时,服务器使用质询-响应机制,该机制不使用明文密码传输,并且不需要安全连接。)