暂无图片
暂无图片
4
暂无图片
暂无图片
暂无图片

MySQL8.0 身份验证插件解读

原创 KevinCui 2023-04-20
1161

在数据库系统中,密码校验规则是防止不良行为和未经授权的访问的关键,可以说,密码就是数据库系统的一道门,也是一道防御线, 并且保证数据库不被恶意攻击的安全的重要部分。

从MySQL5.6到8.0提供了多种身份验证插件,随着版本迭代和新安全加密技术的发展,MySQL也在不停的在加强这层防御。

目前MySQL认证插件种类有如下:

插件名 支持版本 检查说明
mysql_native_password 基于本机密码哈希方法实现身份验证。
sha256_password 基于本机使用SHA-256密码哈希执行身份验证。
caching_sha2_password 实现SHA-256身份验证(如sha256_password),但在服务器端使用缓存。
mysql_clear_password 客户端身份验证插件,可以让客户端将密码以明文形式发送到服务器,而不需要哈希或加密。这个插件内置在MySQL客户端库中。
PAM Pluggable Authentication MySQL Enterprise 使用PAM (Pluggable authentication Modules)来认证MySQL用户。外部身份验证,代理用户支持。
Windows Pluggable Authentication Windows上使用本地Windows服务对客户端连接进行身份验证。
LDAP Pluggable Authentication MySQL Enterprise 使用LDAP(轻量级目录访问协议)通过访问目录服务(如X.500)来认证MySQL用户。
Kerberos Pluggable Authentication MySQL Enterprise 使用Kerberos进行身份验证。MySQL 8.0.26及更高版本中可用windows和linux环境
No-Login Pluggable Authentication mysql_no_login服务器端身份验证插件阻止所有客户端连接到任何使用它的帐户。
Socket Peer-Credential Pluggable Authentication 服务器端auth_socket身份验证插件对通过Unix套接字文件从本地主机连接的客户机进行身份验证。
FIDO Pluggable Authentication MySQL Enterprise MySQL 8.0.27及更高版本中可用,FIDO身份验证允许使用智能卡、安全密钥和生物识别阅读器等设备进行身份验证。
Test Pluggable Authentication MySQL包含一个测试插件,用于检查帐户凭据,并将成功或失败记录到服务器错误日志中。

下面来了解下,常用的加密机制。

Native Pluggable Authentication

MySQL包含一个mysql_native_password插件来实现本地身份验证。目前5.7版本里常用的密码认证,甚至到8.0版本也沿用。早期的版本采用mysql_old_password(4.1之前)是密码哈希方法的身份验证,实现本机身份验证的密码机制。使用服务器的8字节随机加密密码(现已弃用)。到mysql_native_password采用的是20字节随机加密密码。
image.png

SHA1( password ) XOR 
SHA1( "20-bytes random data from server" <concat> SHA1( SHA1( password ) ) )

mysql.user.authentication_string字段采用的如下方式:

SHA1( SHA1( password ) )

由于 mysql_native_password 在 mysql.user 表中 authentication_string 字段存储的是两次哈希 SHA1(SHA1(password)) 计算的值 ,如果两个用户帐户使用相同的密码,那么经过 mysql_native_password 转换后在 mysql.user 表得到的哈希值相同。

mysql> CREATE USER 'nativeuser1'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456'; mysql> CREATE USER 'nativeuser2'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456'; mysql> SELECT user,plugin, authentication_string FROM mysql.user WHERE user like '%nativeuser%'; +-------------+-----------------------+-------------------------------------------+ | user | plugin | authentication_string | +-------------+-----------------------+-------------------------------------------+ | nativeuser1 | mysql_native_password | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | | nativeuser2 | mysql_native_password | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | +-------------+-----------------------+-------------------------------------------+ 2 rows in set (0.00 sec)

备注:
美国国家标准与技术研究院(National Institute of Standards and Technology,NIST)建议SHA-1哈希算法的用户尽快迁移到更安全的SHA-2和SHA-3算法。最迟不晚于2030年12月31号。对于国外大的科技公司,如:Meta,谷歌,微软,Mozilla等在2015年时就差不多完成了对SHA-1算法的升级改造.2017时所有的主流浏览器不再将基于SHA-1的数字证书视为安全证书。因为SHA1和其他哈希算法(例如 MD5)可以很容易就预先计算好常见词语的哈希结果词典,如:字典破解(Dictionary Attack)和暴力破解(Brute Force Attack)方式,匹配到密码。并且很多案例已被证明非常容易破解。

SHA-256 Pluggable Authentication

MySQL为提供更多的安全机制,用户帐户密码实现了SHA-256哈希,分两种认证插件:

  • sha256_password:基本的SHA-256认证。
  • caching_sha2_password:实现SHA-256身份验证(如sha256_password),但在服务器端使用缓存以获得更好的性能,并在MySQL8.0版本中广泛的适用性。

1.sha256_password

使用SHA-256密码哈希执行身份验证的插件。该插件为用户帐户密码实现SHA-256哈希,并进行多轮SHA256 哈希,与本地身份验证相比,这是更强大的加密,暴力破解更难。"sha256"是指插件用于加密的256位摘要长度。"sha2"更笼统地指SHA-2类加密算法,其中256位加密是其中的一种实例。

sha256_password插件存在于服务器和客户端形式:

  • 服务器端插件内置于服务器中,不需要显式加载,也不能通过卸载来禁用它。
  • 客户端插件被内置到libmysqlclient客户端库中,对任何链接到libmysqlclient的程序都可用。

sha256_password需要结合RSA公钥使用,对于使用sha256_password认证和RSA公钥对密码交换的帐号连接,服务器会根据需要向客户端发送RSA公钥。

  • 对于使用sha256_password插件的客户端,当连接到服务器时,密码永远不会以明文形式公开。密码如何传输取决于是否使用安全连接或RSA加密:
  • 如果连接是安全的,则不需要RSA密钥对,也不使用。适用于使用TLS加密的连接。密码以明文形式发送,但由于连接是安全的,因此无法被窥探。
  • sha256_password插件不将共享内存连接视为安全的,即使共享内存传输在默认情况下是安全的。
  • 如果未使用安全连接,且RSA加密不可用,则连接尝试失败,因为在发送密码时将以明文形式暴露。

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

  • 数据库管理员可以提供公钥文件的副本。
  • 可以通过其他方式连接到服务器的客户端用户可以使用SHOW STATUS LIKE 'Rsa_public_key’语句并将返回的键值保存在文件中。

通过SSL和RSA证书和密钥”中的说明创建RSA私钥和公钥对文件。
1.启动时,如下系统变量已启用,如果所有这些条件都成立,服务器会自动在数据目录中生成RSA私钥/公钥对文件:

  • sha256_password_auto_generate_RSA_keys
  • 或 caching_sha2_password_auto_generate_rsa_keys

2.需要指定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

这里可以通过mysql_ssl_rsa_setup官方工具执行指导创建。

3.获取认证key信息

mysql> SHOW STATUS LIKE 'Rsa_public_key'; +----------------+--------------------------------------------------------------+ | Variable_name | Value | +----------------+--------------------------------------------------------------+ | Rsa_public_key | -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx+VWXiKhYLjYPmSYn5AK jlyo258sjlNFTgvJk4A244newoNNCxAuVV5KR+zZgXCEdquz7Va4tFYxDqMK1WkS UKryGingqRxDRrl9zVQDh2Fo5zH42fehND/euDmvVU2xsoklYrLJf4MqjNpqfe3B HK0Obh4UOxQzwxJGnKksp3unM4JZW+snw07v+O9vhkE2/wRTvFCEOO1Ye25tuDqj q4GBjZIvP6oqjpxN/WqSP9hkf2geYKOrWlCjNxJIuR1fVdlUVTG6WZPnkw86sFLB beMUGkpZr3NTyIEyyaxzOOusZrboQ4q687ZrqIZt0nFHpJ8lip0Kf/uwM4CQzFg8 YwIDAQAB -----END PUBLIC KEY----- | +----------------+--------------------------------------------------------------+

备注:
在认证过程中,SHA-256哈希在安全连接和多轮hash转换需要更长的是时间,这样导致性能上出现了一定的影响。

2.caching_sha2_password

从MySQL 8.0.3开始,引入了一个新的身份验证插件 caching_sha2_password,在MySQL 8.0.4中,caching_sha2_password是默认的身份验证插件。是sha256_password身份验证插件功能的超集,实现SHA-256身份验证,同时在服务器端使用缓存以获得更好的性能,并具有更广泛的适用性的附加功能。既解决安全性问题又解决性能问题,因此不推荐使用sha256_password。

使用使用caching_sha2_password进行身份验证的帐户的客户端必须使用安全连接(使用TCP使用TLS/SSL凭据、Unix套接字文件或共享内存进行连接),或者使用RSA密钥对支持密码交换的未加密连接。同时服务器端插件使用sha2_cache_cleaner审计插件作为助手来执行密码缓存管理。sha2_cache_cleaner和caching_sha2_password一样,都是内置的,不需要安装。

Scramble-XOR(SHA256(password), 
SHA256(SHA256(SHA256(password)), Nonce))
Hash entry - account_name -> SHA256(SHA256(user_password))
mysql> SELECT user,plugin, authentication_string FROM mysql.user where user='cachsha256user'; +----------------+-----------------------+-----------------------------------------------------------------------+ | user | plugin | authentication_string | +----------------+-----------------------+-----------------------------------------------------------------------+ | cachsha256user | caching_sha2_password | $A$005$#'a%dc3n!+8yP{,B%VhZp0Tu.EDqFN/7PF/f9PX6Boe35aSYKBkrBVgnc7iB | +----------------+-----------------------+-----------------------------------------------------------------------+ 1 row in set (0.01 sec)

新caching_sha2_password 认证机制下,authentication_string 中的字节如下:

内容 字节数 说明
哈希算法 2字节 目前仅为 $A,表示 SHA256 算法
哈希轮转次数 4字节 目前仅为 $005,表示 5*1000=5000 次
盐(salt) 21字节 用于解决相同密码相同哈希值问题
哈希值 43字节

caching_sha2_password插件相比于sha256_password有这些优势:

  • 在服务器端,内存缓存使重新连接的用户,可以更快地重新认证以前连接的用户。当然第一次链接,缓存里肯定没有用户数据。
  • 无论MySQL链接到哪个SSL库,都可以进行基于RSA的密码交换。
  • 提供了对使用Unix套接字文件和共享内存协议的客户端连接的支持。
    image.png

当然8.0是默认使用这个插件,也可以进行配置:

[mysqld]
caching_sha2_password_private_key_path=myprivkey.pem
caching_sha2_password_public_key_path=mypubkey.pem
caching_sha2_password_digest_rounds=10000

备注:
为了使暴力破解机制更难以猜测密码,在将最终转换存储在mysql.user 表中之前,对密码hash进行多次轮回SHA2 散列,并提供了哈希回合数:caching_sha2_password_digest_rounds(默认5000)。当然会存在一定的性能损失。

对于复制:
复制中可以使用基于RSA密钥对的密码交换连接到主机。这种RSA能力适用于使用caching_sha2_password或sha256_password身份验证插件进行身份验证的帐户。

  • CHANGE MASTER TO语句有用于指定RSA公钥信息的子句。
  • 对于Group Replication,系统变量group_replication_recovery_public_key_path和group_replication_recovery_get_public_key的作用相同。
  • SHOW SLAVE STATUS语句和performance_schema.replication_connection_configuration表显示复制从RSA公钥信息

因为caching_sha2_password 插件在应用缓存的状况下能够疾速认证,缓存清理操作将影响后续客户端连接的身份验证。如:

  • 新创建账号,删除之后重新创建。用户缓存信息从存在内存中。
  • 更改帐户密码后,用户缓存信息从内存中删除。
  • 当用户被RENAME USER重命名时,用户缓存信息从内存中删除。
  • 当执行FLUSH PRIVILEGES时,所有缓存的用户信息从内存中删除。
  • 当服务重新启动时,所有缓存的用户信息从内存中删除。

No-Login Pluggable Authentication

mysql_no_login服务器端身份验证插件阻止所有客户端连接到任何使用它的帐户。

  • 必须能够以提升的权限执行存储的程序和视图,而不会将这些权限暴露给普通用户的帐户。
  • 不允许直接登录,但只能通过代理帐户访问的代理帐户。
[mysqld]
plugin-load-add=mysql_no_login.so
mysql> INSTALL PLUGIN mysql_no_login SONAME 'mysql_no_login.so'; mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE '%login%'; +----------------+---------------+ | PLUGIN_NAME | PLUGIN_STATUS | +----------------+---------------+ | mysql_no_login | ACTIVE | +----------------+---------------+ #创建用户 CREATE USER 'nologin'@'localhost' IDENTIFIED WITH mysql_no_login;

auth_socket

服务器端auth_socket身份验证插件通过Unix套接字文件对从本地主机连接的客户端进行身份验证。该插件使用SO_PEERCRED套接字选项来获取有关运行客户端程序的用户的信息。因此,该插件只能在支持SO_PEERCRED选项的系统上使用,例如Linux。

备注:SO_PEERCRED返回套接字对等体的凭据。 SCM_CREDENTIALS允许传递拥有权限的任何凭据。这是特别有价值的,因为内核将转换id,因此一个pid命名空间中的任务可以发送pid以在另一个命名空间中处理,并确保接收到的pid将引用它想要的相同进程。

该插件的源代码可以作为一个相对简单的示例进行检查,演示如何编写可加载的身份验证插件。

[mysqld]
plugin-load-add=auth_socket.so
mysql> INSTALL PLUGIN auth_socket SONAME 'auth_socket.so'; mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE '%socket%'; +-------------+---------------+ | PLUGIN_NAME | PLUGIN_STATUS | +-------------+---------------+ | auth_socket | ACTIVE | +-------------+---------------+ mysql> CREATE USER 'valerie'@'localhost' IDENTIFIED WITH auth_socket; mysql> ALTER USER 'valerie'@'localhost' IDENTIFIED WITH auth_socket AS 'stephanie';

在连接时都指定–user=valerie 即可。

实例

主流密码插件的配置和创建用户:
配置文件设置:

[mysqld]  
default-authentication-plugin      = caching_sha2_password
#default-authentication-plugin     = mysql_native_password
#default-authentication-plugin     = sha256_password
#创建账号方式: mysql> CREATE USER 'sha256user'@'localhost' IDENTIFIED WITH sha256_password BY 'password'; mysql> CREATE USER 'nativeuser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'; mysql> CREATE USER 'cachsha256user'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'password'; #对比 mysql> SELECT user,plugin, authentication_string FROM mysql.user where user like '%user'; +----------------+-----------------------+----------------------------------------------------------------+ | user | plugin | authentication_string | +----------------+-----------------------+----------------------------------------------------------------+ | cachsha256user | caching_sha2_password | $A$005$`4V7Z(~FQ~aSjYSZy138HTf.hj31c/u3yLRzqQO1qroTUMtzOncmtp5 | | nativeuser | mysql_native_password | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 | | sha256user | sha256_password | $5$y ACe8_xs@$1Tlu5t6myh3oq7Tfn4Otcm.75S9z65k1lO9zzCznV1A | +----------------+-----------------------+----------------------------------------------------------------+ 3 rows in set (0.00 sec)

参考

https://dev.mysql.com/doc/refman/8.0/en/authentication-plugins.html

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论