一、前奏
正常部署项目,发现输入日志为: 提示为无法成功建立链接,链接被拒绝。本地客户端使用账户密码登录,显示 Access denied for user 'root'@'localhost' (using password: YES)
遂使用Navicat 测试远程链接,发现亦不能正常连接,判断可能是密码修改后忘记,或被他人修改。遂进行密码修改操作。
当前版本为 myql8
二、测试修改密码
由于我们这里使用的账号为 root 账号,且密码已遗忘,需要使用 mysql 的无密码登录模式,进行登录,然后对密码进行修改。操作如下:
1.修改 my.cnf 配置文件
一般路径为 \etc\my.cnf 具体以自己安装位置为准。
添加
[mysqld]
skip-grant-tables
示例如下:
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
innodb_buffer_pool_size=1073741824
join_buffer_size=1048576
sort_buffer_size=1048576
max_heap_table_size=33554432
tmp_table_size=33554432
[mysqld]
skip-grant-tables
2.添加完成后手动重启 mysqld 服务
mysqld 是 mysql 的服务端程序。
这里以 centos7.9为例
sudo systemctl restart mysqld
重启成功后,直接使用如下命令可直接登录进mysql
mysql -uroot
3. 将密码置空并设置新密码
use mysql
# 以下为设置root 的认证为空
update user set authentication_string = '' where user = 'root';
为什么不能在这里直接修改密码。
网上有很多说法,说是直接在这里修改密码就可以成功登录。
我靠,我都不知道那些抄袭的有没有试验过,让我们一起来看看user表中 ,authentication_string 这个字段是什么样的
mysql> select user,authentication_string from user;
+------------------+------------------------------------------------------------------------+
| user | authentication_string |
+------------------+------------------------------------------------------------------------+
| mysql.infoschema | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| mysql.session | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| mysql.sys | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED |
| root | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B |
+------------------+------------------------------------------------------------------------+
这里可以看到,authentication_string 是经过处理的一段字符串,而不是密码明文,你使用
update user set authentication_string = '123456' where user = 'root';
修改了,mysql 在校验的时候就通不过了,能修改成功就有鬼了。
so,将此处置空,在正常登录时无需输入密码即可直接登录。
可能会有人说以前的 password 关键字也可以,但是mysql 8中已删除该关键字,则其不可再使用。这里也提一下以前的旧方法。
UPDATE mysql.user SET authentication_string=PASSWORD('newpassword') WHERE User='root' AND Host='localhost';
4.正式开始修改密码
想要正常修改账户密码,需要使用 mysql 提供的修改机制。
ALTER USER 'root'@'localhost' IDENTIFIED BY 'yourpassword';
# 注意,如果这里你的root 账户主机为% 需要使用下面的语句
ALTER USER 'root'@'%' IDENTIFIED BY 'yourpassword';
但是由于 mysql 安全策略限制,我们不能在免密码的登录模式下对密码进行修改,否则会错。
所以我们这里要先退出免密码模式。
将第一步在my.cnf 中添加的skip-grant-tables删除即可。
然后使用命令重新启动mysqld服务即可。
sudo systemctl restart mysqld
执行mysql -u root -p登录数据库,提示输入密码时直接敲回车,刚刚已经将密码置空了。
好了,现在你已经成功进入mysql了,开始修改密码即可。
use mysql;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'yourpassword';
#使用 命令查看一下,确定已修改
mysql> select user,host,plugin,authentication_string from user;
+------------------+-----------+-----------------------+------------------------------------------------------------------------+
| user | host | plugin | authentication_string |
+------------------+-----------+-----------------------+------------------------------------------------------------------------+
| root | localhost | mysql_native_password | *8124124F1231429E1B |
+------------------+-----------+-----------------------+------------------------------------------------------------------------+
#记得最后使用 刷新一下权限
FLUSH PRIVILEGES;
这里可以看到密码已经发生变化。
以下为扩展内容
三、修改密码后的公钥问题。
Caused by: com.mysql.cj.exceptions.UnableToConnectException: Public Key Retrieval is not allowed
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_372]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_372]
at sun.reflect.DelegatingConstructorAccessorImpl.newIns
这个问题是因为从 mysql5.7后,mysql 就默认使用
caching_sha2_password如果我们在修改密码时没有指定 插件,则默认使用的为该插件。
以下为查询资料
mysql_native_password:这是MySQL 5.6和5.7的默认认证插件。它使用SHA1算法进行密码存储和验证,认证速度快,但安全性较低,因为SHA1已被认为不够安全且容易受到攻击 。此外,从MySQL 8.0.34开始,mysql_native_password插件已被弃用,并可能在将来的版本中被移除。caching_sha2_password:这是MySQL 8.0及以后版本的默认认证插件。它使用SHA256算法提供更安全的密码加密,并且引入了密码缓存机制,以提高认证性能。当密码的哈希值缓存在内存中时,可以使用基于SHA256的快速质询-响应机制进行认证。它还支持安全连接,如使用TLS或RSA密钥对进行密码交换 。sha256_password:这个插件使用SHA256算法进行密码加密,提供了比mysql_native_password更高的安全性,但相较于caching_sha2_password,它没有缓存机制,因此在性能上可能稍逊一筹 。mysql_clear_password:此插件允许以明文形式发送密码,主要用于客户端插件,可以与任何需要明文密码的服务器端插件一起使用,但安全性较低 。auth_socket:此插件通过UNIX套接字文件对本地主机的连接进行认证,适合于需要严格控制访问权限的场景 。- 多因素认证(MFA) :MySQL 8.0.27引入了多因素认证功能,可以通过
authentication_policy系统变量来管理,允许指定多重身份校验,提高安全性 。
解决方法
1.1修改插件方式为 mysql_native_password
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'YourPassword';
#修改完记得刷新权限
FLUSH PRIVILEGES;
1.2 保留默认的 caching_sha2_password 方式,设置 ssl相关的配置。
添加allowPublicKeyRetrieval=true和**useSSL=false**
例如
jdbc:mysql://localhost:3306/db?allowPublicKeyRetrieval=true&useSSL=false
[引用自](MySQL Connection String Options for .NET/C# - MySqlConnector)