我模拟存储密码哈希并在登录过程中验证它。
我有一个名为hashPassword(String password)
的方法来获取String密码并通过添加salt返回它的哈希值。
我选择salt作为静态值,在本例中,我为密码选择了相同的值(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
为什么这两个值不相同?
我的代码出了什么问题?
答案 0 :(得分:2)
问题在于:
String hashedPassToStoreInDB = String.valueOf(hashPassword(userDefinedPassword));
在这里:
String hashedInputPassword = String.valueOf(hashPassword(inputPassword));
您正在使用String
方法返回的byte[]
创建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));
答案 1 :(得分:0)
您正在生成byte[]
数组的两个不同实例,其String
表示遵循Object.toString
中的byte[]
表示。
因此,你的两个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[]
如果您需要将String
存储为byte[]
,则可以使用Arrays.toString(myByteArray)
平等地表示它们(对于相等的String
s)。
两个相等密码之间的比较将返回相等的{{1}} s。
答案 2 :(得分:0)
你偶然发现java数组不会覆盖toString。
错误为什么要使用数组:只需连接字符串,然后在结果上使用hashCode()
,就可以获得基本的盐工作:
int hash = (password + salt).hashCode();