Exact same hashing in java as PHP with salt? (SHA-256)

java, php, sha256

Solution

Apart from the order being swapped, it looks like in PHP you're treating the salt value as a literal string to be appended to the password, while in Java you do a hex conversion of the salt first and then use the resulting bytes to update the `MessageDigest`. This will obviously yield different results. Looking only at the salt:

PHP: Salt -> To bytes (literal) -> SHA-256 Java: Salt -> To bytes (unhex) -> SHA-256

I just tried your Java code, and it's absolutely fine. I also tried to hash the same value in PHP as in Java and it gave me identical results.

The Java equivalent to your PHP code would be:

String password = "abcd";
String salt = "5f8f041b75042e56";

try {
    MessageDigest digest = MessageDigest.getInstance("SHA-256");

    return digest.digest((password + salt).getBytes("UTF-8"));
} catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
    return null;
}

After hexing the bytes it returns the following result:

60359BC8A0B09898335AA5A037B1E1B9CE3A1FE0D4CEF13514901FB32F3BCEB0

And in PHP doing:

<?
echo hash('sha256', "abcd"."5f8f041b75042e56");
?>

Returns exactly the same.

Problem

I can simply hash in PHP with a salt: ``` $orig_pw = "abcd"; $salt = 5f8f041b75042e56; $password = hash('sha256', $orig_pw . $salt); ``` (This is not how I implement it, this is just an example. Salt is different for everyone) And with this, the stored password is: ``` bc20a09bc9b3d3e1fecf0ed5742769726c93573d4133dbd91e2d309155fa9929 ``` But if I try to do the same in Java, I get a different result. I tried `String password = "abcd";` ``` byte[] salt = hexStringToByteArray("5f8f041b75042e56"); try { System.out.println(new String(getHash(password, salt))); } catch (NoSuchAlgorithmException e1) { e1.printStackTrace(); } ``` And the two methods: ``` public byte[] getHash(String password, byte[] salt) throws NoSuchAlgorithmException { MessageDigest digest = MessageDigest.getInstance("SHA-256"); digest.reset(); digest.update(salt); try { return digest.digest(password.getBytes("UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return null; } public byte[] hexStringToByteArray(String s) { int len = s.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16)); } return data; } ``` The result is: ``` /¬1¶ĆĽëüFd?[$?¶»_9ËZ»ç¶S‘Ęŗש ``` Which coded to hex is not even close to it: ``` 2fac31b6434c14ebfc46643f5b243fb6bb5f39cb5abb10e7b65391454c97d7a90d0a ``` Can anyone help with this?

Original source