I simulate storing password hashes and validate it in login process.
I have a method called hashPassword(String password)
to get a String password and returns it's hash with adding of salt.
I choose salt an static value and in this example, i choose an identical value for 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;
}
}
But the result is:
what stores in DB: [B@219c9a58
Users hashed password: [B@305918a5
Incorrect
Why this two value is not identical?
What is wrong with my code?
You are generating two different instances of a
byte[]
array, whoseString
representation follows the one fromObject.toString
.Hence the hashes of your two
byte[]
s are different.Try comparing
Arrays.equals(yourSaltedPassword, yourOtherSaltedPassword)
instead.For instance:
Output
If you need to store your
byte[]
s asString
s, you can represent them equally (for equalbyte[]
s) withArrays.toString(myByteArray)
.The comparisons between the two equal passwords will then return equal
String
s.The problem is here:
and here:
You're creating a
String
from thebyte[]
returned fromhashPassword
method, but using the wrong method. Since there's no overload forbyte[]
inString#valueOf
method, it ends callingString#valueOf(Object obj)
which will useObject#toString
internally, and the string representation of an array by itself is meaningless.Use
new String(byte[] byteArray)
instead.You have stumbled on to the fact that java arrays do not override toString.
Bug why use arrays: You can get a basic salt working by just concatenating strings, then using
hashCode()
on the result: