PHP sha256 hash different than Java Guava one

120

Question: PHP sha256 hash different than Java Guava one

I'm trying to validate sha256 hashes generated via Java Guava Hashing class using PHP, but can't seem to do it. I can't touch Java files, so fix has to be done on java error PHP side. Both PHP and Java use UTF-8 encoding. What am I missing?

Java:

package org.test.hash;  import com.google.common.hash.Hashing;  public class Main {     public static void main(String[] args) throws Exception     {         String salt = "0123456789012345";         String password = "password";          System.out.println(             Hashing.sha256().hashUnencodedChars(salt + "|" + password).toString()         );     } } 

Output:

818112d34d341ace8b9325fce61e676a125f733e25c28c9ed172c1f7d2c3aa6c 

PHP:

$salt = "0123456789012345"; $password = "password"; print_r(hash("sha256", $salt . "|" . $password)); 

Output:

1f0a70940ae365e930c51e3de4c0a82f853f7663fc17acd36406982666685703 

Total Answers: 2

76

Answers 1: of PHP sha256 hash different than Java Guava one

It's a string encoding difference, check the following with Python:

>>> from hashlib import sha256 >>> string = "0123456789012345|password"  >>> sha256(string.encode("utf-8")).hexdigest() '1f0a70940ae365e930c51e3de4c0a82f853f7663fc17acd36406982666685703'  >>> sha256(string.encode("utf-16-le")).hexdigest() '818112d34d341ace8b9325fce61e676a125f733e25c28c9ed172c1f7d2c3aa6c'  >>> string.encode("utf-8").hex() '303132333435363738393031323334357c70617373776f7264'  >>> string.encode("utf-16-le").hex() '30003100320033003400350036003700380039003000310032003300340035007c00700061007300730077006f0072006400' 
65

Answers 2: of PHP sha256 hash different than Java Guava one

I figured it out thanks to suggestions from comments. It seems that bad implementation on Java end (using hashUnencodedChars instead of hashString) is causing conversion from source encoding (UTF-8 in my case) to UTF-16LE. Here's a way to fix that on PHP side:

$salt = "0123456789012345"; $password = "password"; $salted = mb_convert_encoding($salt . "|" . $password, "UTF-16LE", "UTF-8") print_r(hash("sha256", $salted)); 

Output:

818112d34d341ace8b9325fce61e676a125f733e25c28c9ed172c1f7d2c3aa6c