Java: storing passwords with a salt and PBKDF2

A site should never store passwords in plain text, and should not store a plain fast hash either. A password hashing function is deliberately slow and takes a salt, a random value stored beside the hash. The salt makes identical passwords produce different hashes and defeats precomputed tables.

Java
import java.security.MessageDigest;
import java.security.SecureRandom;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;

class Main {
  static byte[] derive(char[] password, byte[] salt) throws Exception {
    PBEKeySpec spec = new PBEKeySpec(password, salt, 600_000, 256);
    return SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256").generateSecret(spec).getEncoded();
  }

  public static void main(String[] args) throws Exception {
    byte[] salt = new byte[16];
    new SecureRandom().nextBytes(salt);
    byte[] stored = derive("correct horse".toCharArray(), salt);

    byte[] good = derive("correct horse".toCharArray(), salt);
    byte[] bad = derive("wrong guess".toCharArray(), salt);
    System.out.println("hash length: " + stored.length + " bytes");
    System.out.println("right password: " + MessageDigest.isEqual(stored, good));
    System.out.println("wrong password: " + MessageDigest.isEqual(stored, bad));
  }
}
Read the full lesson