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
仅在 Client 端实现,如本节稍后所述.)
本节描述了缓存 SHA-2 身份验证插件,自 MySQL 5.7.23 起可用。有关原始基本(非缓存)插件的信息,请参见第 6.4.1.5 节“ SHA-256 可插拔身份验证”。
Important
在 MySQL 5.7 中,默认的身份验证插件为mysql_native_password
。从 MySQL 8.0 开始,默认的身份验证插件已更改为caching_sha2_password
。为了使 MySQL 5.7Client 端能够使用通过caching_sha2_password
进行身份验证的帐户连接到 8.0 及更高版本的服务器,MySQL 5.7Client 端库和 Client 端程序支持caching_sha2_password
Client 端身份验证插件。尽管默认身份验证插件有所不同,但与 MySQL 8.0 和更高版本的服务器相比,这提高了 MySQL 5.7Client 端连接功能的兼容性。
与 MySQL 8.0 相比,将 MySQL 5.7 中的caching_sha2_password
支持限制到 Client 端库中的 Client 端插件具有以下含义:
-
MySQL 5.7 中未实现
caching_sha2_password
服务器端插件。 -
MySQL 5.7 服务器不支持创建使用
caching_sha2_password
进行身份验证的帐户。 -
MySQL 5.7 服务器未实现特定于
caching_sha2_password
服务器端支持的系统和状态变量:caching_sha2_password_auto_generate_rsa_keys,caching_sha2_password_private_key_path,caching_sha2_password_public_key_path,Caching_sha2_password_rsa_public_key。
另外,不支持 MySQL 5.7 复制从属服务器使用通过caching_sha2_password
进行身份验证的帐户连接到 MySQL 8.0 复制主服务器。这将涉及将主服务器复制到版本号低于主服务器版本的从服务器,而主服务器通常复制到版本等于或高于主服务器版本的从服务器。
Important
要使用通过caching_sha2_password
插件进行身份验证的帐户连接到 MySQL 8.0 或更高版本的服务器,必须使用支持使用 RSA 密钥对进行密码交换的安全连接或未加密连接,如本节稍后所述。无论哪种方式,caching_sha2_password
插件都使用 MySQL 的加密功能。参见第 6.3 节“使用加密的连接”。
Note
在名称sha256_password
中,“ sha256”是指插件用于加密的 256 位摘要长度。在名称caching_sha2_password
中,“ sha2”更一般地 table 示 SHA-2 类加密算法,其中 256 位加密是其中的一种实例。后一种名称选择为将来扩展可能的摘要长度留出了空间,而无需更改插件名称。
与sha256_password
相比,caching_sha2_password
插件具有以下优势:
-
在服务器端,内存中的高速缓存使先前连接的用户在再次连接时可以更快地重新进行身份验证。 (此服务器端行为仅在 MySQL 8.0 及更高版本中实现.)
-
提供了对使用 Unix 套接字文件和共享内存协议的 Client 端连接的支持。
下 table 显示了 Client 端上的插件名称。
table6.10 SHA-2 身份验证的插件和库名称
插件或文件 | 插件或文件名 |
---|---|
Client-side plugin | caching_sha2_password |
Library file | 无(内置插件) |
以下各节提供了特定于缓存 SHA-2 可插拔身份验证的安装和使用信息:
有关 MySQL 中可插拔身份验证的一般信息,请参见第 6.2.13 节“可插入身份验证”。
安装 SHA-2 可插入身份验证
在 MySQL 5.7 中,caching_sha2_password
插件以 Client 端形式存在。Client 端插件内置于libmysqlclient
Client 端库中,并且可用于针对libmysqlclient
链接的任何程序。
使用 SHA-2 可插入身份验证
在 MySQL 5.7 中,使用caching_sha2_password
Client 端插件可以使用通过caching_sha2_password
服务器端插件进行身份验证的帐户连接到 MySQL 8.0 或更高版本的服务器。这里的讨论假设在 MySQL 8.0 或更高版本的服务器上存在一个名为'sha2user'@'localhost'
的帐户。例如,以下语句创建一个这样的帐户,其中* password
*是所需的帐户密码:
CREATE USER 'sha2user'@'localhost'
IDENTIFIED WITH caching_sha2_password BY 'password';
caching_sha2_password
支持通过安全传输进行连接。如果满足以下条件,caching_sha2_password
还支持通过未加密的连接使用 RSA 进行加密的密码交换:
- MySQL 5.7Client 端库和 Client 端程序是使用 OpenSSL 而不是 yaSSL 编译的。
caching_sha2_password
适用于使用任一软件包编译的发行版,但是 RSA 支持需要 OpenSSL。
Note
仅在 MySQL 5.7.28 之前,才可以使用 yaSSL 替代 OpenSSL 来编译 MySQL。从 MySQL 5.7.28 开始,对 yaSSL 的支持已删除,所有 MySQL 构建都使用 OpenSSL。
- 您希望连接的 MySQL 8.0 或更高版本的服务器被配置为支持 RSA(使用本节后面给出的 RSA 配置过程)。
RSA 支持具有以下 Feature,其中与服务器端有关的所有方面都需要 MySQL 8.0 或更高版本的服务器:
-
在服务器端,两个系统变量分别命名为 RSA 私钥和公钥对文件:caching_sha2_password_private_key_path和caching_sha2_password_public_key_path。如果要使用的密钥文件的名称与系统变量默认值不同,则数据库 Management 员必须在服务器启动时设置这些变量。
-
服务器使用caching_sha2_password_auto_generate_rsa_keys系统变量来确定是否自动生成 RSA 密钥对文件。参见第 6.3.3 节“创建 SSL 和 RSA 证书和密钥”。
-
Caching_sha2_password_rsa_public_key状态变量显示
caching_sha2_password
身份验证插件使用的 RSA 公钥值。 -
拥有 RSA 公钥的 Client 端可以在连接过程中与服务器执行基于 RSA 密钥对的密码交换,如稍后所述。
-
对于通过使用
caching_sha2_password
进行身份验证的帐户进行连接,以及基于 RSA 密钥对的密码交换,服务器默认不会将 RSA 公钥发送给 Client 端。Client 端可以使用所需公用密钥的 Client 端副本,也可以从服务器请求公用密钥。
使用公用密钥的受信任本地副本可以使 Client 端避免 Client 端/服务器协议中的往返,并且比从服务器请求公用密钥更为安全。另一方面,从服务器请求公用密钥更为方便(它不需要 ManagementClient 端文件),并且在安全的网络环境中可以接受。
-
对于命令行 Client 端,请使用--server-public-key-path选项指定 RSA 公钥文件。使用--get-server-public-key选项可从服务器请求公钥。以下程序支持两个选项:mysql,mysqladmin,mysqlbinlog,mysqlcheck,mysqldump,mysqlimport,mysqlpump,mysqlshow,mysqlslap, mysqltest 。
- 对于使用 C API 的程序,通过传递
MYSQL_SERVER_PUBLIC_KEY
选项和文件名来调用mysql_options()以指定 RSA 公钥文件,或者通过传递MYSQL_OPT_GET_SERVER_PUBLIC_KEY
选项来向服务器请求公钥。
- 对于使用 C API 的程序,通过传递
在所有情况下,如果给出了用于指定有效公钥文件的选项,则它优先于从服务器请求公钥的选项。
对于使用caching_sha2_password
插件的 Client 端,连接到 MySQL 8.0 或更高版本的服务器时,密码永远不会以明文形式公开。密码传输的方式取决于是否使用安全连接或 RSA 加密:
-
如果连接安全,则无需使用 RSA 密钥对。这适用于使用 TLS 加密的 TCP 连接,以及 Unix 套接字文件和共享内存连接。密码以明文形式发送,但由于连接安全,因此无法监听。
-
如果连接不安全,则使用 RSA 密钥对。这适用于未使用 TLS 和命名管道连接而未加密的 TCP 连接。 RSA 仅用于 Client 端和服务器之间的密码交换,以防止密码监听。服务器收到加密的密码后,便对其进行解密。加密中使用加扰来防止重复攻击。
-
如果未使用安全连接且 RSA 加密不可用,则连接尝试将失败,因为无法发送密码而不将密码公开为明文。
如前所述,只有使用 OpenSSL 编译 MySQL 5.7 时,才可以使用 RSA 密码加密。使用 yaSSL 编译的 MySQL 5.7 发行版中的 Client 端的含义是,要使用 SHA-2 密码,Client 端必须(必须)使用加密连接来访问服务器。参见第 6.3.1 节“配置 MySQL 以使用加密连接”。
假设已经使用 OpenSSL 编译了 MySQL 5.7,请使用以下过程在 Client 端连接过程中启用 RSA 密钥对用于密码交换。
Important
此过程中与服务器配置有关的某些方面必须在您希望使用 MySQL 5.7Client 端连接到的 MySQL 8.0 或更高版本的服务器上完成,而不是在 MySQL 5.7 服务器上完成。
-
按照第 6.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_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 加密来传输密码。但是,服务器不会将公用密钥发送给 Client 端,并且 Client 端未提供公用密钥,因此它无法加密密码并且连接失败:
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 公钥发送给 Client 端,后者使用它来加密密码并将结果返回给服务器。插件使用服务器端的 RSA 私钥解密密码,并根据密码是否正确来接受或拒绝连接。
或者,如果 Client 端的文件包含服务器所需的 RSA 公钥的本地副本,则可以使用--server-public-key-path选项指定该文件:
shell> mysql --ssl-mode=DISABLED -u sha2user -p --server-public-key-path=file_name
Enter password: password
在这种情况下,Client 端使用公共密钥对密码进行加密并将结果返回给服务器。插件使用服务器端的 RSA 私钥解密密码,并根据密码是否正确来接受或拒绝连接。
用--server-public-key-path选项命名的文件中的公用密钥值应与用caching_sha2_password_public_key_path系统变量命名的服务器端文件中的密钥值相同。如果密钥文件包含有效的公共密钥值,但该值不正确,则会发生拒绝访问的错误。如果密钥文件不包含有效的公共密钥,则 Client 端程序无法使用它。
Client 端用户可以通过两种方式获取 RSA 公钥:
-
数据库 Management 员可以提供公共密钥文件的副本。
-
可以通过其他方式连接到服务器的 Client 端用户可以使用
SHOW STATUS LIKE 'Caching_sha2_password_rsa_public_key'
语句并将返回的键值保存在文件中。
SHA-2 可插入身份验证的缓存操作
在服务器端,caching_sha2_password
插件使用内存缓存来更快地验证以前已连接的 Client 端。对于仅支持caching_sha2_password
Client 端插件的 MySQL 5.7,此服务器端缓存因此在使用 MySQL 5.7Client 端连接到的 MySQL 8.0 或更高版本的服务器上进行。有关缓存操作的信息,请参阅MySQL 8.0 参考手册中的SHA-2 可插入身份验证的缓存操作。