I am porting a web application from Ruby to Java and would like to allow the users to log in without resetting their passwords. Here is the Ruby code that generates the hash using the pbkdf2 gem:
PBKDF2.new { |p|
p.password = password
p.salt = salt
p.iterations = 10000
}.hex_string
Reading the source for the Ruby gem, it is using OpenSSL::Digest.new("sha256") as the default hashing function and generates a value of 32 bytes, which converts to a 64 character string using 'unpack("H*")'.
So, in Java I tried the following:
public String generatePasswordHash(String password, String salt) throws NoSuchAlgorithmException, InvalidKeySpecException
{
char[] chars = password.toCharArray();
byte[] saltBytes =salt.getBytes();
PBEKeySpec spec = new PBEKeySpec(chars, saltBytes, 1000, 256);
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
byte[] hash = skf.generateSecret(spec).getEncoded();
BigInteger bi = new BigInteger(1, hash);
return bi.toString(16);
}
Testing both pieces of code with password = "apassword" and salt = "somesalt", I get the following results.
Ruby: 3fa1eb7544ca49b1f371eb17d24bf0010c433fa263a84aff7df446741371706b
Java: 77a7c0b1ea9760d0b1ef02e7a2633c40ccd7848ee4fa822ec71b5794e476f354
I tested the Ruby and Java hex string encoding and they work the same so the problem looks to be in the hashing algorithm or perhaps the way the Strings are converted to byte arrays.