MySQL 提供了两个身份验证插件,它们为用户帐户密码实现了 SHA-256 哈希算法。
sha256_password
: 实现基本 SHA-256 身份验证。caching_sha2_password
: 实现 SHA-256 身份验证(类似于sha256_password
),但在服务器端使用缓存以提高性能,并具有其他功能以扩展适用范围。
本节描述原始的非缓存 SHA-2 身份验证插件。有关缓存插件的信息,请参见 第 8.4.1.1 节,“缓存 SHA-2 可插拔身份验证”.
在 MySQL 9.0 中,caching_sha2_password
是默认身份验证插件;mysql_native_password
不再可用。有关此更改对服务器操作以及服务器与客户端和连接器兼容性的影响的信息,请参见 caching_sha2_password 作为首选身份验证插件.
由于 caching_sha2_password
是 MySQL 9.0 中的默认身份验证插件,并且提供了 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 位加密是其中的一种实例。后者的名字选择留下了扩展可能摘要长度的空间,而无需更改插件名称。
下表显示了服务器端和客户端的插件名称。
以下部分提供了特定于 SHA-256 可插拔身份验证的安装和使用信息。
有关 MySQL 中可插拔身份验证的一般信息,请参见 第 8.2.17 节,“可插拔身份验证”.
sha256_password
插件以服务器端和客户端形式存在。
服务器端插件内置于服务器中,无需显式加载,也无法通过卸载它来禁用它。
客户端插件内置于
libmysqlclient
客户端库中,可用于链接到libmysqlclient
的任何程序。
要设置使用 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
支持通过安全传输连接。如果MySQL使用OpenSSL编译,并且您要连接到的MySQL服务器已配置为支持RSA(使用本节后面给出的RSA配置过程),sha256_password
还支持使用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公钥发送到客户端。但是,如果在客户端主机上提供了公钥的副本,则客户端可以使用它来节省客户端/服务器协议中的往返行程对于这些命令行客户端,使用
--server-public-key-path
选项指定RSA公钥文件:mysql、mysqladmin、mysqlbinlog、mysqlcheck、mysqldump、mysqlimport、mysqlshow、mysqlslap、mysqltest。对于使用C API的程序,调用
mysql_options()
通过传递MYSQL_SERVER_PUBLIC_KEY
选项和文件名称来指定RSA公钥文件。对于副本,使用
CHANGE REPLICATION SOURCE TO
语句,并使用SOURCE_PUBLIC_KEY_PATH
选项来指定RSA公钥文件。对于组复制,group_replication_recovery_get_public_key
系统变量具有相同的用途。
对于使用sha256_password
插件的客户端,连接到服务器时密码永远不会以明文形式显示。密码传输的方式取决于是否使用了安全连接或RSA加密
如果连接是安全的,则RSA密钥对是不必要的,也不会使用。这适用于使用TLS加密的连接。密码以明文形式发送,但由于连接是安全的,因此无法被窃取。
注意与
caching_sha2_password
不同,sha256_password
插件不会将共享内存连接视为安全,即使共享内存传输默认情况下是安全的。如果连接不安全,并且可以使用RSA密钥对,则连接将保持未加密。这适用于未使用TLS加密的连接。RSA仅用于客户端和服务器之间的密码交换,以防止窃取密码。当服务器收到加密的密码时,它会对其进行解密。在加密中使用混淆来防止重复攻击。
如果没有使用安全连接并且RSA加密不可用,则连接尝试将失败,因为密码无法在不以明文形式显示的情况下发送。
要使用sha256_password
的RSA密码加密,客户端和服务器都必须使用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'
语句并将返回的密钥值保存到文件中。