3

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.

2
  • Possible duplicate of How to convert a byte array to a hex string in Java? Commented Mar 16, 2016 at 7:59
  • @artjom B. It was the conversion from the byte array to hex string that was causing the problem, I used a String Builder to do the conversion process instead and it worked as intended. Commented Mar 20, 2016 at 8:58

1 Answer 1

6

It is the BigInteger that is killing the leading 0.

Hashes are not integers, they are an array of 8-bit bytes. Do not try to convert to a BigInteger.

Either use it as a byte[] or encode as a hexadecimal or Base64 string. To match PHP hexadecimal encode hashedPassword.

PHP is returning a hexadecimal string encoded hash because raw_output is set to FALSE.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, it the BigInteger conversion was the culprit, I used a String Builder to create the hex string instead and it worked correctly.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.