如何在JavaFX注册场景下实现密码发送至MySQL前的哈希加密?
JavaFX+MySQL密码哈希存储问题修复方案
核心问题分析
- 哈希密码未实际存入数据库:
createUser方法中生成了哈希后的securePassword,但创建User对象时仍使用原始明文密码,导致数据库存储的不是哈希值。 - 盐值转换错误:
getSalt方法直接调用salt.toString(),返回的是字节数组的对象标识(如[B@123456),而非盐的实际字符串内容,导致哈希计算逻辑失效。 - 缺失盐值存储逻辑:盐是密码哈希的核心依赖,必须与哈希后的密码一同存入数据库,否则后续无法验证密码。
修复后的代码实现
1. 修正盐值生成方法(用Base64编码转换字节数组)
private static String getSalt() throws NoSuchAlgorithmException { SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); byte[] salt = new byte[16]; sr.nextBytes(salt); // 使用Base64将字节数组转为可存储的字符串 return Base64.getEncoder().encodeToString(salt); }
2. 修正用户创建逻辑(传入哈希密码与盐值)
private void createUser() throws NoSuchAlgorithmException { DatabaseHandler databaseHandler = new DatabaseHandler(); String passwordToHash = passwordField.getText(); String salt = getSalt(); String securePassword = get_SHA_256_SecurePassword(passwordToHash, salt); System.out.println(securePassword); String name = firstNameField.getText(); String lastName = lastNameField.getText(); String email = emailField.getText(); // 传入哈希后的密码与盐值(需同步修改User类结构) User user = new User(name, lastName, email, securePassword, salt); databaseHandler.signUpUser(user); }
3. 修正数据库插入逻辑(新增盐值字段存储)
public void signUpUser(User user) { // 新增salt字段的插入语句(需先给latesttable表添加salt字段) String insertNew = "INSERT INTO latesttable (FirstName, LastName, email, password, salt)\n" + "VALUES (?,?,?,?,?)"; try { PreparedStatement preparedStatement = getDbConnection().prepareStatement(insertNew); preparedStatement.setString(1, user.getFirstName()); preparedStatement.setString(2, user.getLastName()); preparedStatement.setString(3, user.getEmail()); preparedStatement.setString(4, user.getPassword()); // 存储哈希后的密码 preparedStatement.setString(5, user.getSalt()); // 存储盐值 preparedStatement.execute(); } catch (SQLException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } }
4. 同步修改User类(添加盐值属性)
public class User { private String firstName; private String lastName; private String email; private String password; private String salt; // 带盐值的构造方法 public User(String firstName, String lastName, String email, String password, String salt) { this.firstName = firstName; this.lastName = lastName; this.email = email; this.password = password; this.salt = salt; } // 盐值的getter/setter public String getSalt() { return salt; } public void setSalt(String salt) { this.salt = salt; } // 其他属性的getter/setter... }
5. 密码验证逻辑示例(登录时使用)
// 验证输入密码是否匹配存储的哈希值 public boolean verifyPassword(String inputPassword, String storedHash, String storedSalt) { String computedHash = get_SHA_256_SecurePassword(inputPassword, storedSalt); return computedHash.equals(storedHash); }
内容的提问来源于stack exchange,提问作者sqlcoder
相关产品推荐
相关产品推荐

