I'm having some difficulty producing the same encrypted password using the PBKDF2 algorithm on both Java and PHP.
I'm using the following Java implementation to generate the hash with a random byte array which is 16 bytes in size. I'm then storing the hash and salt separately in a MySQL database, however when I go to do the same operation in PHP using the salt retrieved from the database, I get almost the exact same encryption except the hash has a leading 0 and I cannot for the life of me figure out why.
Java:
public String hashPassword(String password, byte[] salt){ char[] passwordChars = password.toCharArray(); PBEKeySpec spec = new PBEKeySpec( passwordChars, salt, ITERATIONS, KEY_LENGTH ); SecretKeyFactory key = null; try { key = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } byte[] hashedPassword = null; try { hashedPassword = key.generateSecret(spec).getEncoded(); } catch (InvalidKeySpecException e) { // TODO Auto-generated catch block e.printStackTrace(); } return String.format("%x", new BigInteger(hashedPassword)); } I found the above code at https://adambard.com/blog/3-wrong-ways-to-store-a-password/
PHP:
$query = $database->query('SELECT * FROM USERS'); $password = 'hello'; $iterations = 1000; foreach($query as $user){ $hash = hash_pbkdf2("sha1", $password, $user['salt'], $iterations, 40, false); } echo $hash; Note: There is only one user stored in the database, I know the above code isn't great, I created it quickly for testing purposes.
For both implementations I'm using an iteration count of 1000, a key length of 160 in Java and a key length of 40 in PHP (to compensate for setting raw-output to false)
Java Output - 971f0dddc1bc2e899f2bca178f16ea79bfbbb13 PHP Output - 0971f0dddc1bc2e899f2bca178f16ea79bfbbb13 Any help is much appreciated, thank you.