介绍从MySQL8.0.4开始,MySQL默认的认证插件从mysql_native_password变成了caching_sha2_password。相应的,libmysqlclient也使用caching_sha2_password作为默认的认证机制。原因在此之前,MySQL5.6/5.7使用的默认密码插件是mysql_native_password。mysql_native_password特性不需要加密连接。插件验证速度很快,但是不够安全,因为mysql_native_password使用的是SHA1算法,而NIST(美国国家标准技术研究院)早就建议停止使用SHA1算法,因为SHA1和其他哈希算法(例如MD5)很容易被破解。事实上,从MySQL5.6开始,引入了更安全的认证机制:ha256_password认证插件。它使用加盐密码进行多轮SHA256哈希(数千轮哈希,更难暴力破解)以确保更安全的哈希转换。然而,建立安全连接和多轮散列是非常耗时的。虽然安全性更高,但验证速度不够快。改进MySQL试图结合两个世界的优点。于是在MySQL-8.0.3中引入了一个新的认证插件caching_sha2_password。作为sha256_password的替代品,在sha256_password的基础上进行了改进,弥补了不足,既解决了安全问题,也解决了性能问题。同时,sha256_password也将走出时代的浪潮。MySQL希望在未来的版本中将其删除。使用sha256_password进行认证的MySQL账户建议切换到caching_sha2_password。结果,由于默认认证机制的改变,在使用MySQL8.0时出现了很多相关的问题。网上的教程大多是教人改回mysql_native_password认证方式mysql_native_password。但笔者认为,MySQL更改默认插件是出于更好的安全考虑。如果有MySQL服务要在公网使用,建议尽量使用caching_sha2_password作为认证插件。示例:使用老版本客户端连接报错:shell>mysql-uroot-pERROR2059(HY000):Authenticationplugin'caching_sha2_password'cannotbeloaded具体机制分析mysql_native_passwordmysql_native_password作为MySQL5.6/5.7的默认密码插件。它的优点是支持挑战-响应(challenge-response),这是一种非常快速的认证机制,无需在网络中发送实际密码,也不需要加密连接。当客户端连接到MySQL实例时,首先需要从服务器获取一个20字节的随机数。此外,mysql_native_password使用新的哈希算法进行身份验证。对于用户的原始密码,mysql.user表的authentication_string列中存储了SHA1(SHA1(password))两次哈希计算的结果。用户密码经过哈希计算后保存,不加盐。通过以上处理,MySQL数据库本身就已经很安全了。但是,随着时间的推移,目前存在两个潜在的风险:SHA1哈希算法也变得相对容易破解。相同的密码具有相同的哈希值。之前的SHA1、MD5等哈希算法已经不安全了,更安全的哈希算法如SHA256、SHA512也相继推出。作为数据存储的最终承载者,应该使用更新的加密机制。cache_sha2_password密码认证机制下的caching_sha2_password,其改进如下:authentication_string中存储的哈希值是加盐后的值,即使两个不同的用户密码相同,计算机中存储的哈希值也不同。哈希算法升级为更安全的SHA256算法。哈希算法的轮数从原来的两倍增加到5000次。轮次越多,每次计算哈希值的代价越大,破解难度越大。密码使用TLS加密或RSA密钥传输从客户端传输到服务器。Caching_sha2_password通信过程分析对于大多数连接尝试,当密码的哈希值缓存在内存中时,其验证是基于SHA256挑战-响应机制(相比mysql_native_password中基于SHA1的挑战-响应机制快),下图演示了有hash缓存时的验证过程。challenge-response的认证方式从图中我们可以看出,client对密码进行多次hash加密生成一个Scramble发送给server,server检查内存缓存中是否存在该表项。当该值存在于缓存中证明连接合法时,服务器会告诉客户端快速认证成功:向客户端发送一个fast_auth_success包,并发送确认信息。然后服务端就可以和客户端正常通信了。当没有这种缓存时,caching_sha2_password需要使用安全连接(SSL/STL)进行密码交换。考虑到用户变化和FLUSHPRIVILEGES操作的频率比较低,在大多数情况下,在不建立安全连接的情况下使用基于挑战-响应的认证。这节省了建立安全连接所需的资源。下图总结了完整的验证过程。从图中我们可以看出,服务器收到Scramble后,发现缓存中没有对应的值。服务器会使用完整的认证过程告诉客户端建立安全连接:向客户端发送一个perform_full_authentication包,然后客户端收到服务器的公钥(如果公钥文件已经存在则省略此步骤)。如果已经基于建立了安全连接(SSL/STL),可以直接将明文密码发送给服务器。如果没有安全连接,客户端会向服务器发起请求获取公钥(或指定服务器的公钥文件),用公钥加密密码后发送给服务器。服务器通过SHA256算法计算哈希值,判断用户认证是否通过,如果通过则向客户端发送OK报文。然后服务端就可以和客户端正常通信了。下面详细解释一下RSA非对称加密的通信过程:首先必须明确一个概念:在非对称加密算法中,有两个密钥:公钥和私钥。如果用公钥加密,只有对应的私钥才能解密;反之亦然。RSA密钥交换过程:1、服务器生成一对密钥,并将公钥公开给对方(明文发送给客户端)。2、客户端用服务器的公钥加密密码后发送给服务器。3.服务器用对应的私钥对加密后的信息进行解密。因为客户端用公钥加密后的信息只能用服务器的私钥解密,所以这个连接过程可以看作是加密通信。Somethingtonote对默认认证插件的更改意味着:所有在MySQL8.0.4之后创建的新用户将默认使用caching_sha2_password作为认证插件。mysql>SELECTUSER,PLUGINFROMmysql.`user`;+----------------+----------------------+|用户|插件|+----------------+---------------------+|根|缓存_sha2_密码||mysql.信息模式|缓存_sha2_密码||mysql.会话|缓存_sha2_密码||mysql.sys|-+--------------------+6rowsinset(0.06sec)libmysqlclient默认使用caching_sha2_password,可以通过手动修改插件切换到其他认证.使用caching_sha2_password插件的客户端在连接到服务器时不会使用命名密码。密码的传输方式取决于密码是使用安全连接还是RSA加密:如果连接是安全的,则可能不会使用RSA密钥。适用于使用TLS加密的TCP连接,以及Unix套接字文件和共享内存连接。密码以明文形式发送,但无法窃听,因为连接是安全的。如果连接不安全,可以使用RSA密钥对。适用于未使用TLS加密的TCP连接和命名管道连接。RSA仅用于客户端和服务器之间的密码交换,以防止密码拦截。服务器收到用公钥加密的密码后,用私钥解密。加密中使用随机字符串以防止重复攻击。在MySQL8.0.3及更高版本中。默认情况下自动完成用于加密交换的RSA密钥对。关于主从复制如果用于复制的用户使用了caching_sha2_password认证插件,并且没有开启安全连接(在group_replication_recovery中开启SSL支持),MySQL会使用RSA密钥对进行密码交换,你可以手动交换public主节点的密钥复制到从节点的服务器也可以设置为:自动为请求加入组的节点提供公钥。复制本身支持加密连接。在MySQL8.0.4中,添加了对RSA加密的复制支持。CHANGEMASTER以下参数可用于启用基于caching_sha2_passwordRSA密钥的密码交换:指定RSA公钥路径-MASTER_PUBLIC_KEY_PATH="key_file_path"#从服务器获取RSA公钥-GET_MASTER_PUBLIC_KEY={0|1}GroupReplication可以通过如下参数来启用基于caching_sha2_passwordRSA密钥的密码交换:#指定RSA公钥路径--group-replication-recovery-public-key-path#从中获取RSA公钥服务器--group-replication-recovery-get-public-key数据库升级数据库升级到MySQL8.0.4会发生什么?升级前创建的用户不会被身份验证插件更改。升级后创建的用户默认使用aching_sha2_password认证插件。除非使用--default-authentication-plugin手动指定身份验证插件。因为升级前的现有用户不会改变。因此,这些用户在使用升级后仍然可以连接到旧版本的客户端。因此,libmysqlclient支持mysql_options()CAPI函数的MYSQL_DEFAULT_AUTH选项。(对于MySQL包中可用的基于libmysqlclient的客户端工具,--default-auth命令行选项可用于相同目的。)推荐使用cache_sha2_password因为更安全。并将libmysqlclient升级到MySQL8.0.4或更高版本以支持新的身份验证插件。参考【MySQL8.0.4:NewDefaultAuthenticationPlugin】caching_sha2_password】https://dev.mysql.com/blog-archive/mysql-8-0-4-new-default-authentication-plugin-caching_sha2_password【得物科技谈MySQL8.0:新增认证插件]https://segmentfault.com/a/1190000040733952[MySQL8.0密码认证机制升级,不知道可能会导致业务不可用!!]https://mp.weixin.qq.com/s/jfoH6D8NfoaNN7eexbzKGA[群复制安装部署|全面理解MySQL8.0GroupReplication】https://mp.weixin.qq.com/s/sydu0alXDECcHm5GNMvtdA
