java - 从 MySQL 数据库验证散列密码

标签 java eclipse hash verify

我在 Eclipse 中使用 Java,并在创建新用户时将散列密码存储在我的数据库中。这是用这段代码完成的..

String hashed_password = Password.hashPassword(passwordField.toString());
String query = "insert into user (username, password, usertype, license_code) values (?, ?, ?, ?)";
PreparedStatement pst = connection.prepareStatement(query);
pst.setString(1, userNameTextField.getText());
pst.setString(2, hashed_password);

我遗漏了一些与密码无关的其他细节,但是,我的散列值存储在数据库中。然后我登录,并执行以下代码...

String test_passwd = passwordField.getText();
String test_hash = "$2a$12$N773YstmtU/1zIUe9An.r.P9U5BQp4o6.Qjk.J.zhA6ZtFytYuOZC";

System.out.println("Testing BCrypt Password hashing and verification");
System.out.println("Test password: " + test_passwd);
System.out.println("Test stored hash: " + test_hash);
System.out.println("Hashing test password...");
System.out.println();

String computed_hash = Password.hashPassword(test_passwd);
System.out.println("Test computed hash: " + computed_hash);
System.out.println();
System.out.println("Verifying that hash and stored hash both match for the test password...");
System.out.println();

String compare_test = Password.checkPassword(test_passwd, test_hash)
? "Passwords Match" : "Passwords do not match";
String compare_computed = Password.checkPassword(test_passwd, computed_hash)
? "Passwords Match" : "Passwords do not match";

System.out.println("Verify against stored hash:   " + compare_test);
System.out.println("Verify against computed hash: " + compare_computed);

test_hash 变量是存储在新用户代码数据库中的散列密码。当我登录时,我知道我使用的密码与我在新用户提示中使用的密码相同。

但是,这是我的结果:

Test stored hash: $2a$12$N773YstmtU/1zIUe9An.r.P9U5BQp4o6.Qjk.J.zhA6ZtFytYuOZC
Hashing test password...

Test computed hash: $2a$12$rbBleRV4gyLaY4.ZZ4fjiOrLW423TWYqKmv0ejws7mmFd2N3/eieK

Verifying that hash and stored hash both match for the test password...

Verify against stored hash:   Passwords do not match
Verify against computed hash: Passwords Match

结果表明密码当时和那里的哈希密码匹配,但与数据库中的哈希密码不匹配,尽管初始密码相同。

这是我对密码进行哈希处理并验证它的代码...

public class Password {
// Define the BCrypt workload to use when generating password hashes. 10-31 is a valid value.
private static int workload = 12;

/**
 * This method can be used to generate a string representing an account password
 * suitable for storing in a database. It will be an OpenBSD-style crypt(3) formatted
 * hash string of length=60
 * The bcrypt workload is specified in the above static variable, a value from 10 to 31.
 * A workload of 12 is a very reasonable safe default as of 2013.
 * This automatically handles secure 128-bit salt generation and storage within the hash.
 * @param password_plaintext The account's plaintext password as provided during account creation,
 *               or when changing an account's password.
 * @return String - a string of length 60 that is the bcrypt hashed password in crypt(3) format.
 */
public static String hashPassword(String password_plaintext) {
    String salt = BCrypt.gensalt(workload);
    String hashed_password = BCrypt.hashpw(password_plaintext, salt);

    return(hashed_password);
}

/**
 * This method can be used to verify a computed hash from a plaintext (e.g. during a login
 * request) with that of a stored hash from a database. The password hash from the database
 * must be passed as the second variable.
 * @param password_plaintext The account's plaintext password, as provided during a login request
 * @param stored_hash The account's stored password hash, retrieved from the authorization database
 * @return boolean - true if the password matches the password of the stored hash, false otherwise
 */
public static boolean checkPassword(String password_plaintext, String stored_hash) {
    boolean password_verified = false;

    if(null == stored_hash || !stored_hash.startsWith("$2a$"))
        throw new java.lang.IllegalArgumentException("Invalid hash provided for comparison");

    password_verified = BCrypt.checkpw(password_plaintext, stored_hash);

    return(password_verified);
}

最佳答案

我不熟悉 Java,但在我看来,您从密码输入字段中获取值的方式有误,也许您应该检查一下:

// In the registration form
passwordField.toString()

// In the login form
passwordField.getText()

关于java - 从 MySQL 数据库验证散列密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31168568/

相关文章:

java - 当 .class 不在默认包中时 FindClass 返回 null

python - 在 Eclipse 中刷新 PyDev 导入路径

Java DB Derby 和 Netbeans 7.1 构建问题

java - 克隆或复制 JAXB XML block

java - 使用 pdfbox 计算 pdf 中的图像数量

java - 具有相同名称的线程

c++ - ubuntu 13.04 上的 Eclipse C++ 插件

c# - 哈希函数的字节到字符串?

python - 如何在不必手动处理数据 block 的情况下散列大文件?

ruby - 在 ruby​​ 的哈希中找到最低和最高值