MySQL数据库MD5加密密码后原密码无法登录的解决方案咨询
解决方案
问题原因
- 首次登录时你用明文密码和数据库存储的明文做比对,校验通过后直接将库内密码更新为MD5哈希值
- 后续登录逻辑仍然直接拿用户输入的明文和库内的MD5哈希字符串比对,二者内容完全不一致,自然校验失败
修复步骤
1. 调整校验逻辑
将登录校验流程改为:
- 首先根据用户名查询库中存储的密码
- 对用户输入的明文密码计算MD5值,和库中存储的密码比对,匹配则直接登录成功
- 如果MD5比对不匹配,再用用户输入的明文和库中存储的密码比对:
- 匹配则说明该用户的密码还未做哈希迁移,登录成功后将库内明文密码更新为对应MD5值
- 不匹配则返回账号密码错误
2. 代码修改参考
同时你现有代码存在SQL注入高危风险,建议替换为PreparedStatement处理SQL语句,核心修改后的代码如下:
public void validateLogin(){ DatabaseConnection connectNow = new DatabaseConnection(); Connection connectDB = connectNow.getConnection(); // 按用户名查询存储的密码,用PreparedStatement防注入 String queryPwdSql = "SELECT password FROM user_account WHERE username = ?"; String updatePwdSql = "UPDATE user_account SET password = MD5(?) WHERE username = ?"; try{ String inputUsername = usernameTextField.getText(); String inputPwd = enterPasswordField.getText(); // 先查询对应用户的存储密码 PreparedStatement pwdQueryStmt = connectDB.prepareStatement(queryPwdSql); pwdQueryStmt.setString(1, inputUsername); ResultSet pwdRs = pwdQueryStmt.executeQuery(); if(pwdRs.next()){ String storedPwd = pwdRs.getString("password"); // 计算输入密码的MD5值,也可直接调用MySQL的MD5函数处理 String inputPwdMd5 = org.apache.commons.codec.digest.DigestUtils.md5Hex(inputPwd); boolean loginSuccess = false; // 先比对MD5 if(storedPwd.equals(inputPwdMd5)){ loginSuccess = true; }else if(storedPwd.equals(inputPwd)){ // 明文比对成功,说明未迁移,更新密码为MD5 loginSuccess = true; PreparedStatement updateStmt = connectDB.prepareStatement(updatePwdSql); updateStmt.setString(1, inputPwd); updateStmt.setString(2, inputUsername); updateStmt.executeUpdate(); // 不需要全局的smecher.j变量了,每个用户只会触发一次更新 } if(loginSuccess){ login1(); text1 = storedPwd; }else{ loginMessageLabel.setText("Invalid login, please try again"); } }else{ loginMessageLabel.setText("Invalid login, please try again"); } lol(); }catch(Exception e){ e.printStackTrace(); }finally{ // 按需关闭连接、Statement、ResultSet资源 } }
注意事项
- MD5属于不安全的哈希算法,无加盐的情况下很容易被彩虹表破解,后续建议替换为bcrypt、PBKDF2等带盐值的慢哈希算法存储密码
- 你原代码中全局的
smecher.j变量仅能触发一次密码更新,多用户场景下其他用户的密码无法完成哈希迁移,上述代码已经去掉了该全局变量的依赖,每个用户首次登录时都会自动完成自身密码的哈希转换
内容的提问来源于stack exchange,提问作者Adelin Cărăbaș
相关产品推荐
相关产品推荐

