当前位置: 首页 > 知识库问答 >
问题:

用盐存储和验证散列密码

索嘉胜
2023-03-14

我模拟存储密码散列,并在登录过程中验证它。

我有一个名为hashPassword(字符串密码)的方法来获取字符串密码,并通过添加盐返回它的哈希值。

我选择一个静态值,在本例中,我选择一个相同的密码值(hello123

public class T1 {

public static void main(String[] args) {
    String userDefinedPassword = "hello123";
    String hashedPassToStoreInDB = String.valueOf(hashPassword(userDefinedPassword));
    System.out.println("what stores in DB: " + hashedPassToStoreInDB);
    // store in database

    //Password Verify
    String inputPassword = "hello123";
    String hashedInputPassword = String.valueOf(hashPassword(inputPassword));
    System.out.println("Users hashed password: " + hashedInputPassword);

    if (hashedPassToStoreInDB.equals(hashedInputPassword)) {
        System.out.println("Correct");
    } else {
        System.out.println("Incorrect");
    }
}

private static byte[] hashPassword(String password) {
    byte[] salt = new byte[16];
    byte[] hash = null;
    for (int i = 0; i < 16; i++) {
        salt[i] = (byte) i;
    }
    try {
        KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 128);
        SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        hash = f.generateSecret(spec).getEncoded();

    } catch (NoSuchAlgorithmException nsale) {
        nsale.printStackTrace();

    } catch (InvalidKeySpecException ikse) {
        ikse.printStackTrace();
    }
    return hash;
}
}

但结果是:

what stores in DB: [B@219c9a58
Users hashed password: [B@305918a5
Incorrect

为什么这两个值不相同?

我的代码有什么问题?

共有3个答案

汪永春
2023-03-14

您偶然发现了一个事实,java数组不会覆盖toString。

Bug why use Array(为什么使用数组):只需连接字符串,然后对结果使用hashCode(),就可以得到一个基本的salt:

int hash = (password + salt).hashCode();
南宫鸿晖
2023-03-14

您正在生成一个字节[]数组的两个不同实例,该数组的字符串表示形式遵循对象的表示形式。toString

因此,两个字节[]的哈希值是不同的。

尝试比较数组。等于(yourSaltedPassword,yourOtherSaltedPassword)

例如:

byte[] foo = {1,2};
byte[] bar = {1,2};
System.out.println(foo == bar);
System.out.println(String.valueOf(foo).equals(String.valueOf(bar)));
System.out.println(Arrays.equals(foo, bar));

输出

false
false
true

如果需要将byte[]s存储Strings,则可以使用数组将它们表示为相等的byte[]s。toString(myByteArray)

两个相等密码之间的比较将返回相等的Strings。

戚令秋
2023-03-14

问题在于:

String hashedPassToStoreInDB = String.valueOf(hashPassword(userDefinedPassword));

在这里:

String hashedInputPassword = String.valueOf(hashPassword(inputPassword));

您正在从hashPassword方法返回的byte[]创建字符串,但使用了错误的方法。由于String#valueOf方法中的byte[]没有重载,因此它结束调用String#valueOf(Object obj),后者将在内部使用Object#toString,数组的字符串表示本身是没有意义的。

改用新字符串(byte[]byteArray)

String hashedPassToStoreInDB = new String(hashPassword(userDefinedPassword));
//...
String hashedInputPassword = new String(hashPassword(inputPassword));

 类似资料:
  • 我用这个教程来帮助我,当用户创建一个帐户时,对他们的密码进行加盐和散列,然后当用户输入密码登录时,将这些密码带回来并进行比较。 在这个图坦卡蒙中,它们有两个我想调用的函数。 和 我随后自己创建了另一个函数,它会爆炸结果,因此我可以从整个have中剥离加盐字符串。 所以当我在数据库中插入数据时,它看起来像这样 请注意,最后一列包含第三列中字符串的最后一部分。 因此,最后一步是登录时,用户将输入他们的

  • 我正在使用以下代码创建哈希密码和salt: 我正在数据库中存储HashedPassword和Salt。 现在我要验证用户登录时的密码: 这不起作用,我得到了一个完全不同的哈希密码,而不是存储在数据库中的密码。据我所知,您应该在用户登录时输入的密码之前预置salt,然后运行相同的哈希密码函数。上面不是等价于那个吗?

  • 问题内容: 我正在开发一个小型的Web应用程序,该应用程序在内部对用户进行身份验证。一旦用户通过身份验证,我的Web应用程序便会将一些信息(例如userID和Person的名称)传递给第三方Web应用程序。第三方开发人员建议我们对值进行哈希处理和加盐处理。 原谅我的无知,但这到底意味着什么? 我正在用Java编写应用程序。因此,我打算做的是使用Apache Commons Digest Utils

  • 在我的登录PHP文件中,我有这些 在我的注册PHP文件中,我有这个。 现在,基本上我使它哈希密码,并插入自己的数据库注册。确实如此。 然而,它无法核实。这两个结果给出了两个不同的哈希,我不知道我可能做错了什么。我也试着让它再次散列输入并检查数据库中的password_hash,但那不起作用... 正确的使用方法是什么? (另外,$passSign和$userInput是输入字段,它确实获取用户名/

  • 我想在C#中使用PBKDF2加胡椒和盐来散列密码。我对密码学有点陌生,所以如果我错了,请随时纠正我。 我之所以使用Rfc2898DeriveBytes类,是因为(根据其他Stackoverflow用户的说法)bcrypt和其他哈希算法在C#中不受本机支持和验证,因此可能会造成安全威胁。这篇文章的目的不是开始讨论哪种哈希算法是最好的。 我的目标是:每个密码都会得到一个随机的盐和胡椒,密码会经过一定数

  • 我试图学习密码学,用散列和盐析在数据库中保存密码,所以我决定做一个登录系统来实现这个系统。 我的数据库包括 UserID int PK 用户名varchar(250) Salt varbinary(64) 密码varbinary(64) RegDate日期时间 电子邮件varchar(250) 我正在使用PBKDF2,但似乎这不是散列/盐析方法,如果不是呢? 如果是这样,我做得对吗? 我的钥匙 将