直接update authentication_string = password('xxx')会登录失败,因未刷新权限、plugin字段不匹配旧哈希格式、password_expired为y被强制中断;alter user则自动同步哈希格式、重置过期状态并支持显式指定插件。

因为 PASSWORD() 函数生成的哈希值不带盐、算法固定且已知,攻击者能用彩虹表批量反查,而且它和现代认证插件(如 caching_sha2_password)根本不兼容。
为什么直接 UPDATE authentication_string = PASSWORD('xxx') 会登录失败
你执行了 UPDATE mysql.user SET authentication_string = PASSWORD('123') WHERE user = 'root',但后续无法登录,常见原因有三个:
- 没执行
FLUSH PRIVILEGES→ 权限缓存未刷新,新值压根没加载 - 该用户行的
plugin字段是caching_sha2_password(5.7.21+ 可能已启用),而PASSWORD()输出的是 41 字节旧式 SHA-1 哈希,插件拒绝识别 -
password_expired字段为Y,即使密码对了,首次登录也会被强制中断并要求重置
ALTER USER 为什么必须用,而不是绕过它
ALTER USER 不只是改密码哈希,它同步更新一整套认证元数据:
- 自动写入匹配当前
plugin的哈希格式(比如mysql_native_password用双 SHA-1,caching_sha2_password用 SHA-256) - 重置
password_last_changed和password_expired字段,避免静默拦截 - 如果目标插件不是默认值,必须显式指定:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456'
MySQL 5.7 和 8.0 的关键差异点
别混淆两个版本的“失效”程度:
- 在 MySQL 5.7.6+ 中,
PASSWORD()函数仍存在但已 弃用;SET PASSWORD = PASSWORD('x')语法还能跑,但官方不保证行为一致 - 在 MySQL 8.0+ 中,
PASSWORD()函数被 彻底移除,连函数调用都会报错FUNCTION password does not exist - 5.7 默认插件是
mysql_native_password,8.0 默认是caching_sha2_password,后者不接受PASSWORD()输出的任何值
真正容易被忽略的是:即使你用 ALTER USER 成功设了密码,如果客户端驱动不支持目标认证插件(比如老版 MySQL Connector/J 5.x 连 8.0 的 caching_sha2_password 用户),照样连不上——得升级驱动或显式降级插件。











