2

I'm researching password security and user log-in, and more specifically storing and matching salted password hashes in databases. I understand the basics of salting and hashing, but I don't understand how I am supposed to check against the stored hash-value on a log-in attempt, when the salt is randomly generated before every hash?

public static void test(String password) throws NoSuchAlgorithmException, InvalidKeySpecException {
    int iterations = 65536;
    char[] passChar = password.toCharArray();
    SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
    byte[] salt = new byte[16];
    random.nextBytes(salt);

    PBEKeySpec spec = new PBEKeySpec(passChar, salt, iterations, 512);
    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    byte[] hash = factory.generateSecret(spec).getEncoded();

    System.out.println(iterations + ":\n" + toHex(salt) + ":\n" + toHex(hash));
}
brisdalen
  • 210
  • 1
  • 2
  • 10
  • 1
    Possibly duplicate of https://stackoverflow.com/questions/34515560/compare-two-hashed-password-using-same-salt-using-sha-256-algorith-in-java-spri – Mak Sep 09 '19 at 09:08
  • 1
    The salt needs to be stored too, since `hash = passwd + salt`. – Kayaman Sep 09 '19 at 09:21
  • 1
    @Kayaman But the salt can be stored as is? – brisdalen Sep 09 '19 at 09:30
  • @brisdalen yes. Salt is meant to prevent [pre-made tables](https://en.wikipedia.org/wiki/Rainbow_table) for hash cracking. It's not sensitive information per se. – Kayaman Sep 09 '19 at 10:53

1 Answers1

3

The salt of the password should be stored alongside the hash. Sometimes this is done as a part of the hash (e.g. the first x characters of the hash are the salt), sometimes separately (e.g. another column).

When checking the password, you should not generate a new random salt, but instead use the one generated and stored before.

So you create another hash using the user-provided password and the stored salt, and then check if this matches the stored hash.

Most passwordEncoders provide a method that does this for you, for example, check out this article that explains how to use BCrypt Password Encoder.

Bram
  • 988
  • 7
  • 10