升级到 MySQL 8.0 后,可能会遇到如下报错,常发生在连接 MySQL 或配置复制关系的时候。
ERROR 2061 (HY000): Authentication plugin ‘caching_sha2_password’ reported error: Authentication requires secure connection.
网络上通常建议的解决方案是将 default_authentication_plugin 修改为 mysql_native_password 来解决。虽然可以规避报错,但是在 MySQL 8.1 版本 mysql_native_password 旧插件将被废弃,到时还是要直面 caching_sha2_password 插件。本篇文章将详细解读新的认证插件。
MySQL 8.1 发行说明:The mysql_native_password authentication plugin now is deprecated and subject to removal in a future version of MySQL. CREATE USER, ALTER USER, and SET PASSWORD operations now insert a deprecation warning into the server error log if an account attempts to authenticate using mysql_native_password as an authentication method.
mysql_native_password 是 MySQL 5.6 和 5.7 版本默认的认证插件,其优点是速度快支持 challenge-response 机制,无需在网路上发送实际的密码,并且不需要加密连接。
服务端使用 OpenSSL 库中的函数对输入的密码进行 SHA-1 哈希,生成 hash_stage1,再将生成的 hash_stage1 进行二次 SHA-1 哈希,生成 hash_stage2,然后再将 hash_stage2 转换为 16 进制。最后生成的字符串就是我们在 mysql.user 中看到的authentication_string 字段。
其加密过程使用 Python 实现的代码如下。
import hashlib
def compute_sha1_hash(data):
sha1 = hashlib.sha1()
sha1.update(data)
return sha1.digest()
password = "abc123".encode('utf-8')
hash_stage1 = compute_sha1_hash(password)
hash_stage2 = compute_sha1_hash(hash_stage1)
print('*%s'%hash_stage2.hex().upper())
随着技术发展,mysql_native_password 被验证不再安全,原因如下:
刚才介绍了 mysql_native_password 插件不再安全,容易被破解。从 MySQL 8.0.4 版本开始,默认用户认证插件由 mysql_native_password 更改为 caching_sha2_password 提供了更强的安全性。
caching_sha2_password 底层使用的加密算法(SHA-256)早在 sha256_password 这个认证插件( MySQL 5.6 中引入的)中就使用了。虽然 sha256_password 足够安全,但是由于它要求使用安全连接或使用 RSA 密钥对进行密码交换的未加密连接,因此其身份验证的效率较低。caching_sha2_password 在 sha256_password 的基础上,新增了一个内存缓存,用于存储哈希密码,以加快认证速度。
caching_sha2_password 对密码安全性要求更高,要求用户认证过程中在网络传输的密码是加密的:
RSA 使用的公钥和私钥,默认存储在 datadir 目录下:
private_key.pem RSA公钥
public_key.pem RSA私钥
如果使用 caching_sha2_password 认证方式,MySQL 会要求连接开启 SSL,或者使用 RSA 对密码进行加密,否则连接可能会报如下的错误:
mysql -u user3 -pabc123 -h127.0.0.1 --ssl-mode=DISABLED
ERROR 2061 (HY000): Authentication plugin ‘caching_sha2_password’ reported error: Authentication requires secure connection.
MySQL 客户端可以通过命令行参数 server-public-key-path 指定有效的 RSA Public Key 路径:
mysql -u user3 -pabc123 -h127.0.0.1 --ssl-mode=DISABLED --server-public-key-path=/data/mysql/data/public_key.pem
如果本地没有 RSA public key,可以在登录时从服务端下载 Public Key。相比上一个方法,这种方法不需要在客户端本地维护public key 文件,使用更加简单。但是在登录阶段,需要从服务端下载 public key,会增加第一次验证下载的耗时。
配置复制关系时,如果复制用户也是使用 caching_sha2_password 插件,那么需要配置公钥。
CHANGE REPLICATION SOURCE TO SOURCE_PUBLIC_KEY_PATH = 'key_file_name'
或者配置该参数,自动获取公钥,无需额外配置。
CHANGE REPLICATION SOURCE TO GET_SOURCE_PUBLIC_KEY = {0|1}
对于 MGR ,如果设置 group_replication_ssl_mode=DISABLED ,则也必须使用下面的变量来指定 RSA 公钥,否则报错:
两个参数,配置其中一个即可,考虑到拷贝 RSA 公钥到各节点麻烦,建议设置 group_replication_recovery_get_public_key=ON 。