PasswordTools.java
package eu.javaexperience.password;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import eu.javaexperience.text.Format;
public class PasswordTools
{
public static final PasswordModel ALWAYS_PASS = new ReadOnlyPassword()
{
@Override
public boolean authenticate(String nonce, String password)
{
return true;
}
};
public static final PasswordModel ALWAYS_DENY = new ReadOnlyPassword()
{
@Override
public boolean authenticate(String nonce, String password)
{
return false;
}
};
public static PasswordModel createPlainFixedPassword(final String passwd)
{
return new ReadOnlyPassword()
{
@Override
public boolean authenticate(String nonce, String password)
{
return passwd.equals(password);
}
};
}
public static String generateSalt() throws NoSuchAlgorithmException
{
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
byte[] salt = new byte[16];
sr.nextBytes(salt);
return salt.toString();
}
public static String generateSaltedHashPBKDF2(String password) throws NoSuchAlgorithmException, InvalidKeySpecException
{
int iterations = 1000;
char[] chars = password.toCharArray();
byte[] salt = generateSalt().getBytes();
PBEKeySpec spec = new PBEKeySpec(chars, salt, iterations, 64 * 8);
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] hash = skf.generateSecret(spec).getEncoded();
return iterations + ":" + Format.toHex(salt) + ":" + Format.toHex(hash);
}
public static boolean validateSaltedPasswordPBKDF2(String originalPassword, String storedPassword) throws NoSuchAlgorithmException, InvalidKeySpecException
{
String[] parts = storedPassword.split(":");
int iterations = Integer.parseInt(parts[0]);
byte[] salt = Format.fromHex(parts[1]);
byte[] hash = Format.fromHex(parts[2]);
PBEKeySpec spec = new PBEKeySpec(originalPassword.toCharArray(), salt, iterations, hash.length * 8);
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] testHash = skf.generateSecret(spec).getEncoded();
int diff = hash.length ^ testHash.length;
for(int i = 0; i < hash.length && i < testHash.length; i++)
{
diff |= hash[i] ^ testHash[i];
}
return diff == 0;
}
}