mysql 8.0 默认使用 caching_sha2_password 是因 mysql_native_password 依赖已被弃用的 sha1,存在哈希碰撞、明文协商及无加密通道风险;caching_sha2_password 采用加盐+5000轮 sha256 并强制 tls/rsa 加密,兼顾安全与缓存加速。

MySQL 8.0 默认用 caching_sha2_password,不是为了“炫技”,而是 SHA1 已被 NIST 明确建议弃用,mysql_native_password 的哈希碰撞风险和明文协商机制在生产环境已不满足基础安全水位。
为什么 caching_sha2_password 替掉了 mysql_native_password
根本原因是 mysql_native_password 底层依赖 SHA1:它把密码做两次 SHA1 哈希(SHA1(SHA1(password)))存进 mysql.user.authentication_string。两个用户设相同密码,哈希值就完全一样——这等于变相泄露了密码一致性,攻击者可据此定向爆破。
caching_sha2_password 改用加盐 + 5000 轮 SHA256,每次生成的哈希值都不同,且盐值和轮数直接写死在认证流程里,无法绕过。
- SHA1 碰撞攻击已在实验室条件下实操成功,NIST 要求 2026 年起全面停用
-
mysql_native_password的 challenge-response 协议不强制加密通道,中间人可截获协商数据 -
caching_sha2_password要求 TLS 或 RSA 加密传输密码,或走 Unix socket 本地认证
caching_sha2_password 真的比 sha256_password 快吗
是的,但快的前提是「连接复用」。它把首次认证后的凭证缓存在服务端内存中,后续同用户短时间内的连接直接查缓存,跳过完整 SHA256 计算。
- 首次连接耗时 ≈
sha256_password(都要做 5000 轮 SHA256) - 缓存命中时连接耗时下降 60%~80%,尤其对短连接高频应用(如 PHP-FPM、Serverless 场景)明显
- 缓存默认 TTL 是 300 秒,超时或用户密码变更会自动失效
- 注意:
mysql_native_password没有缓存概念,每次连接都重算,但计算量小(SHA1),所以单次更快
Navicat / JDBC 连不上,真是 caching_sha2_password 的锅?
不全是。真正卡住你的,往往是客户端没走对协议路径:
- Navicat ≤ 12.1 默认用旧版 libmysqlclient,不支持
caching_sha2_password的 RSA 密钥交换流程 - JDBC 驱动
mysql-connector-java低于 8.0.9 会直接抛Unknown system variable 'caching_sha2_password'错误 - PHP 的
mysqli和PDO_MySQL扩展至今(2026 年)仍不支持该插件,必须切回mysql_native_password - 如果你用的是 Docker 或 K8s,还要检查容器内 client lib 版本——镜像 base 可能还是 Ubuntu 20.04 自带的 8.0.28 以下版本
要不要永久切回 mysql_native_password?
除非你明确知道以下三点,否则不建议全局降级:
- 所有客户端(含监控、备份、ETL 工具)都已确认兼容
caching_sha2_password - 数据库暴露在公网或不可信内网,且无法强制 TLS —— 这时降级反而更危险(明文协商)
- 你接受密码策略退化:比如无法设置
PASSWORD EXPIRE INTERVAL 90 DAY,也无法启用双因子(MySQL 8.0+ 的authentication_ldap_sasl仅适配新插件)
最常被忽略的一点:default_authentication_plugin = mysql_native_password 写进 my.cnf 只影响新创建用户,已存在的用户 plugin 不变——你得手动 ALTER USER ... IDENTIFIED WITH mysql_native_password,否则 root 还是连不上。











