存储和验证盐哈希密码(Store and validate hashed password with

2019-10-21 14:01发布

我模拟存储密码散列值和在登录过程中进行验证。

我有一个名为方法hashPassword(String password)得到一个字符串密码并加盐返回它的哈希值。

我选择盐的静态值和在这个例子中,我选择密码(相同的值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

为什么这两值是不相同?

什么是错我的代码?

Answer 1:

问题就在这里:

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

和这里:

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

你要创建一个Stringbyte[]从返回hashPassword方法,但是使用了错误的方法。 由于有一个为没有过载byte[]String#valueOf方法,则结束主叫String#valueOf(Object obj)将使用Object#toString内部,并且通过自身的阵列的字符串表示是没有意义的。

使用new String(byte[] byteArray)来代替。

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


Answer 2:

要生成的两个不同的实例byte[]数组,其String表示如下从所述一个Object.toString

因此,你的两个散列byte[] s为不同。

尝试比较Arrays.equals(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作为String S,你同样可以代表他们(平等byte[] S)与Arrays.toString(myByteArray)

那么两个相等的口令之间的比较将返回相同String秒。



Answer 3:

您无意中发现了这样的事实:Java数组不覆盖的toString。

错误为什么使用数组:你可以得到一个基本的盐仅通过连接字符串的工作,然后使用hashCode()的结果:

int hash = (password + salt).hashCode();


文章来源: Store and validate hashed password with salt
标签: java hash