Java SHA256 outputs different hash to PHP SHA256?

Finbarr picture Finbarr · Jan 13, 2011 · Viewed 13.2k times · Source

PHP code:

echo hash('sha256', 'jake');

PHP output:

cdf30c6b345276278bedc7bcedd9d5582f5b8e0c1dd858f46ef4ea231f92731d

Java code:

String s = "jake";
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(s.getBytes(Charset.forName("UTF-8")));
byte[] hashed = md.digest();
String s2 = "";
for (byte b : hashed) {
    s2 += b;
}
System.out.println(s2);

Java output:

-51-1312107528211839-117-19-57-68-19-39-43884791-1141229-4088-12110-12-223531-11011529

I had expected the two to return the same result. Obviously, this is not the case. How can I get the two to match up or is it impossible?

EDIT: I had made a mistake, think I have the answer to the question now anyway.

Answer

Jon Skeet picture Jon Skeet · Jan 13, 2011

Well, the very first thing you need to do is use a consistent string encoding. I've no idea what PHP will do, but "jake".getBytes() will use whatever your platform default encoding is for Java. That's a really bad idea. Using UTF-8 would probably be a good start, assuming that PHP copes with Unicode strings to start with. (If it doesn't, you'll need to work out what it is doing and try to make the two consistent.) In Java, use the overload of String.getBytes() which takes a Charset or the one which takes the name of a Charset. (Personally I like to use Guava's Charsets.UTF_8.)

Then persuade PHP to use UTF-8 as well.

Then output the Java result in hex. I very much doubt that the code you've given is the actual code you're running, as otherwise I'd expect output such as "[B@e48e1b". Whatever you're doing to convert the byte array into a string, change it to use hex.