8.4.1.3 SHA-256 插件式认证
MySQL 提供了两个认证插件,用于实现 SHA-256 加密用户帐户密码:
-
sha256_password
: 实现基本的 SHA-256 认证。 -
caching_sha2_password
: 实现 SHA-256 认证(类似于sha256_password
),但在服务器端使用缓存,以提高性能,并具有更广泛的适用性。
本节描述了原始非缓存 SHA-2 认证插件。有关缓存插件的信息,请见第8.4.1.2节,“缓存 SHA-2 可插拔认证”。
在 MySQL 8.4 中,caching_sha2_password
是默认认证插件,而不是 mysql_native_password
(已弃用)。有关该更改对服务器操作和与客户端和连接器的兼容性的影响,请见caching_sha2_password 作为首选认证插件。
由于 caching_sha2_password
是 MySQL 8.4 的默认认证插件,并且提供了 sha256_password
认证插件的超集,sha256_password
已弃用;预计将在未来的 MySQL 版本中删除。使用 sha256_password
认证的 MySQL 帐户应迁移到使用 caching_sha2_password
。
要使用 sha256_password
插件认证的帐户连接到服务器,您必须使用 TLS 连接或未加密的连接,以支持密码交换使用 RSA 密钥对,后续在本节中描述。无论哪种方式,sha256_password
插件都使用 MySQL 的加密功能。见第8.3节,“使用加密连接”。
在名称 sha256_password
中,“sha256” 指的是插件使用的 256 位摘要长度。在名称 caching_sha2_password
中,“sha2” 指的是 SHA-2 加密算法家族的一部分,256 位加密是其中的一种实例。后者名称选择留出了将来可能的摘要长度扩展的空间,而不需要更改插件名称。
以下表格显示了插件名称在服务器和客户端两端。
表8.17 SHA-256 认证插件和库名称
Plugin or File | Plugin or File Name |
---|---|
服务器插件 | sha256_password |
客户端插件 | sha256_password |
库文件 | 无(插件是内置的) |
以下部分提供了 SHA-256 可插拔认证的安装和使用信息:
关于 MySQL 中的插件式认证信息,请见第8.2.17节,“插件式认证”。
安装 SHA-256 插件式认证
sha256_password
插件存在于服务器和客户端形式:
-
服务器端插件是服务器的一部分,不需要明确加载,也不能被卸载。
-
客户端插件是
libmysqlclient
客户端库的一部分,对任何使用libmysqlclient
的程序可用。
使用 SHA-256 插件式认证
要使用 sha256_password
插件对账户进行 SHA-256 密码散列,请使用以下语句,其中 password
是所需的账户密码:
CREATE USER 'sha256user'@'localhost'
IDENTIFIED WITH sha256_password BY 'password';
服务器将将 sha256_password
插件分配给账户,并使用 SHA-256 加密密码,存储这些值在 mysql.user
系统表的 plugin
和 authentication_string
列中。
(如果 sha256_password
是默认插件,不需要使用 IDENTIFIED WITH
子句;可以使用 authentication_policy
指定默认插件。)
sha256_password
支持安全传输连接。 sha256_password
也支持使用 RSA 加密密码交换,如果 MySQL 使用 OpenSSL 编译,并且您想要连接的 MySQL 服务器已配置支持 RSA(使用后续部分中的 RSA 配置过程)。
RSA 支持具有以下特点:
-
在服务器端,两个系统变量命名 RSA 私钥和公钥对文件:
sha256_password_private_key_path
和sha256_password_public_key_path
。数据库管理员必须在服务器启动时将这些变量设置为使用的密钥文件名称,如果密钥文件名称与系统变量默认值不同。 -
服务器使用
sha256_password_auto_generate_rsa_keys
系统变量确定是否自动生成 RSA 密钥对文件。请见第8.3.3节,“创建 SSL 和 RSA 证书和密钥”。 -
Rsa_public_key
状态变量显示sha256_password
认证插件使用的 RSA 公钥值。 -
拥有RSA公钥的客户端可以在连接过程中与服务器进行RSA密钥对密码交换,后续将进行描述。
-
对于使用
sha256_password
和RSA公钥对密码交换的账户连接,服务器将在需要时将RSA公钥发送给客户端。但是,如果客户端主机上已经有公钥副本,客户端可以使用它来在客户端/服务器协议中节省一轮trip:-
对于这些命令行客户端,可以使用
--server-public-key-path
选项指定RSA公钥文件:mysql,mysqladmin,mysqlbinlog,mysqlcheck,mysqldump,mysqlimport,mysqlshow,mysqlslap,mysqltest。 -
对于使用C API的程序,调用
mysql_options()
,将RSA公钥文件指定为MYSQL_SERVER_PUBLIC_KEY
选项和文件名。 -
对于复制,使用
CHANGE REPLICATION SOURCE TO
语句,使用SOURCE_PUBLIC_KEY_PATH
选项指定RSA公钥文件。对于Group Replication,group_replication_recovery_get_public_key
系统变量具有相同的作用。
-
对于使用sha256_password
插件的客户端,密码从不以明文形式暴露在服务器连接时。密码传输的方式取决于是否使用安全连接或RSA加密:
-
如果连接是安全的,RSA密钥对是unnecessary且不被使用。这适用于使用TLS加密的连接。密码以明文形式发送,但是因为连接是安全的,因此不能被窃听。
Note与
caching_sha2_password
不同,sha256_password
插件不将共享内存连接视为安全,即使共享内存传输是安全的默认设置。 -
如果连接不安全,并且存在RSA密钥对,连接将保持未加密。这适用于使用TLS以外的加密连接。RSA仅用于客户端和服务器之间的密码交换,以防止密码窃听。当服务器接收加密密码时,它将其解密。用于加密的混淆使得重复攻击不可能。
-
如果不使用安全连接且RSA加密不可用,连接尝试将失败,因为密码不能作为明文发送。
要使用RSA密码加密与sha256_password
,客户端和服务器都必须使用OpenSSL编译,不是其中之一。
假设MySQL已经使用OpenSSL编译,以下是启用RSA密钥对用于客户端连接过程中的密码交换的步骤:
-
使用第8.3.3节,“创建SSL和RSA证书和密钥”中的指令创建RSA私钥和公钥对文件。
-
如果私钥和公钥文件位于数据目录,并且命名为
private_key.pem
和public_key.pem
(sha256_password_private_key_path
和sha256_password_public_key_path
系统变量的默认值),服务器将自动使用它们在启动时。否则,为了明确指定密钥文件名,设置系统变量到服务器选项文件中。如果文件位于服务器数据目录,不需要指定完整路径名:
[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进行密码交换。假设使用未加密连接。例如:
$> mysql --ssl-mode=DISABLED -u sha256user -p
Enter password: password
对于sha256user
的连接尝试,服务器确定sha256_password
是适当的身份验证插件,并将其激活(因为在CREATE USER
时间指定的)。插件找到连接不是加密的,因此需要使用RSA加密传输密码。在这种情况下,插件将RSA公钥发送给客户端,客户端使用它加密密码并将结果返回给服务器。插件使用服务器端的RSA私钥解密密码,并根据密码是否正确接受或拒绝连接。
服务器将RSA公钥发送给客户端,如有需要。然而,如果客户端有包含服务器所需的RSA公钥的本地副本,可以使用--server-public-key-path
选项指定文件:
$> 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
系统变量指定的文件中的公钥值相同。如果公钥文件包含有效的公钥值,但值不正确,访问被拒绝错误将发生。如果公钥文件不包含有效的公钥,客户端程序不能使用。在这种情况下,sha256_password
插件将公钥发送给客户端,就像没有指定--server-public-key-path
选项一样。
客户端用户可以通过以下两种方式获取RSA公钥:
-
数据库管理员可以提供公钥文件副本。
-
可以连接到服务器的客户端用户可以使用
SHOW STATUS LIKE 'Rsa_public_key'
语句并将返回的键值保存到文件中。