6.4.1.5 SHA-256 可插拔身份验证

MySQL 提供了两个身份验证插件,用于对用户帐户密码实施 SHA-256 哈希:

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

  • caching_sha2_password:实现 SHA-256 身份验证(如sha256_password),但在服务器端使用缓存可提高性能,并具有其他功能可更广泛地应用。

本节描述了原始的非缓存 SHA-2 身份验证插件。有关缓存插件的信息,请参见第 6.4.1.4 节“缓存 SHA-2 可插入身份验证”

Important

要使用通过sha256_password插件进行身份验证的帐户连接到服务器,必须使用支持使用 RSA 密钥对进行密码交换的 TLS 连接或未加密连接,如本节稍后所述。无论哪种方式,sha256_password插件都使用 MySQL 的加密功能。参见第 6.3 节“使用加密的连接”

Note

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

下 table 显示了服务器端和 Client 端上的插件名称。

table6.11 SHA-256 身份验证的插件和库名称

插件或文件插件或文件名
Server-side pluginsha256_password
Client-side pluginsha256_password
Library file无(内置插件)

以下各节提供特定于 SHA-256 可插拔身份验证的安装和使用信息:

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

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

sha256_password插件以服务器和 Client 端形式存在:

  • 服务器端插件内置于服务器中,无需显式加载,也无法通过卸载禁用。

  • Client 端插件内置在libmysqlclientClient 端库中,可用于针对libmysqlclient链接的任何程序。

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

要设置使用sha256_password插件进行 SHA-256 密码哈希处理的帐户,请使用以下语句,其中* password *是所需的帐户密码:

CREATE USER 'sha256user'@'localhost'
IDENTIFIED WITH sha256_password BY 'password';

服务器将sha256_password插件分配给该帐户,并使用它通过 SHA-256 加密密码,并将这些值存储在mysql.user系统 table 的pluginauthentication_string列中。

前面的说明不假定sha256_password是默认身份验证插件。如果sha256_password是默认的身份验证插件,则可以使用更简单的CREATE USER语法。

要使用默认身份验证插件设置为sha256_password来启动服务器,请将这些行放入服务器选项文件中:

[mysqld]
default_authentication_plugin=sha256_password

这将导致默认情况下将sha256_password插件用于新帐户。结果,无需显式命名插件即可创建帐户并设置其密码:

CREATE USER 'sha256user'@'localhost' IDENTIFIED BY 'password';

default_authentication_plugin设置为sha256_password的另一个结果是,要使用其他插件创建帐户,必须明确指定该插件。例如,要使用mysql_native_password插件,请使用以下语句:

CREATE USER 'nativeuser'@'localhost'
IDENTIFIED WITH mysql_native_password BY 'password';

sha256_password支持通过安全传输进行连接。如果满足以下条件,sha256_password还支持通过未加密的连接使用 RSA 进行加密的密码交换:

  • MySQL 是使用 OpenSSL 而不是 yaSSL 编译的。 sha256_password适用于使用任一软件包编译的发行版,但是 RSA 支持需要 OpenSSL。

Note

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

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

RSA 支持具有以下 Feature:

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

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

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

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

  • 对于通过使用sha256_password进行身份验证的帐户进行的连接以及基于 RSA 公钥对的密码交换,服务器会根据需要将 RSA 公钥发送给 Client 端。但是,如果 Client 端主机上有公用密钥的副本,则 Client 端可以使用它来保存 Client 端/服务器协议中的往返行程:

  • 对于这些命令行 Client 端,请使用--server-public-key-path选项指定 RSA 公钥文件:mysql,mysqltest 和(自 MySQL 5.7.23 起)mysqladminmysqlbinlogmysqlcheckmysqldumpmysqlimportmysqlpumpmysqlshowmysqlslap mysqltest **。

    • 对于使用 C API 的程序,通过传递MYSQL_SERVER_PUBLIC_KEY选项和文件名来调用mysql_options()以指定 RSA 公钥文件。

    • 对于复制从属,不能使用基于 RSA 密钥对的密码交换来连接到使用sha256_password插件进行身份验证的帐户的主服务器。对于此类帐户,只能使用安全连接。

对于使用sha256_password插件的 Client 端,连接到服务器时,密码永远不会显示为明文。密码传输的方式取决于是否使用安全连接或 RSA 加密:

  • 如果连接安全,则无需使用 RSA 密钥对。这适用于使用 TLS 加密的连接。密码以明文形式发送,但由于连接安全,因此无法监听。

Note

caching_sha2_password不同,sha256_password插件不会将共享内存连接视为安全,即使默认情况下共享内存传输也是安全的。

  • 如果连接不安全,并且 RSA 密钥对可用,则该连接将保持未加密状态。这适用于未使用 TLS 加密的连接。 RSA 仅用于 Client 端和服务器之间的密码交换,以防止密码监听。服务器收到加密的密码后,便对其进行解密。加密中使用加扰来防止重复攻击。

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

如前所述,只有 MySQL 是使用 OpenSSL 编译的,RSA 密码加密才可用。使用 yaSSL 编译的 MySQL 发行版的含义是,要使用 SHA-256 密码,Client 端必须(必须)使用加密连接来访问服务器。参见第 6.3.1 节“配置 MySQL 以使用加密连接”

Note

要对sha256_password使用 RSA 密码加密,Client 端和服务器都必须使用 OpenSSL 进行编译,而不仅仅是其中之一。

假设已使用 OpenSSL 编译 MySQL,请使用以下过程在 Client 端连接过程中启用 RSA 密钥对用于密码交换:

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

[mysqld]
sha256_password_private_key_path=myprivkey.pem
sha256_password_public_key_path=mypubkey.pem

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

[mysqld]
sha256_password_private_key_path=/usr/local/mysql/myprivkey.pem
sha256_password_public_key_path=/usr/local/mysql/mypubkey.pem
  • 重新启动服务器,然后连接到服务器并检查Rsa_public_key状态变量值。该值将不同于此处显示的值,但应为非空值:
mysql> SHOW STATUS LIKE 'Rsa_public_key'\G
*************************** 1. row ***************************
Variable_name: Rsa_public_key
        Value: -----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDO9nRUDd+KvSZgY7cNBZMNpwX6
MvE1PbJFXO7u18nJ9lwc99Du/E7lw6CVXw7VKrXPeHbVQUzGyUNkf45Nz/ckaaJa
aLgJOBCIDmNVnyU54OT/1lcs2xiyfaDMe8fCJ64ZwTnKbY2gkt1IMjUAB5Ogd5kJ
g8aV7EtKwyhHb0c30QIDAQAB
-----END PUBLIC KEY-----

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

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

shell> mysql --ssl-mode=DISABLED -u sha256user -p
Enter password: password

对于sha256user进行的此连接尝试,服务器确定sha256_password是适当的身份验证插件并调用它(因为这是在CREATE USER时间指定的插件)。该插件发现连接未加密,因此需要使用 RSA 加密来传输密码。在这种情况下,该插件会将 RSA 公钥发送给 Client 端,后者使用它来加密密码并将结果返回给服务器。插件使用服务器端的 RSA 私钥解密密码,并根据密码是否正确来接受或拒绝连接。

服务器根据需要将 RSA 公钥发送给 Client 端。但是,如果 Client 端的文件包含服务器所需的 RSA 公钥的本地副本,则可以使用--server-public-key-path选项指定该文件:

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

--server-public-key-path选项命名的文件中的公用密钥值应与用sha256_password_public_key_path系统变量命名的服务器端文件中的密钥值相同。如果密钥文件包含有效的公共密钥值,但该值不正确,则会发生拒绝访问的错误。如果密钥文件不包含有效的公共密钥,则 Client 端程序无法使用它。在这种情况下,sha256_password插件会将公钥发送到 Client 端,就像未指定--server-public-key-path选项一样。

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

  • 数据库 Management 员可以提供公共密钥文件的副本。

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