#1
  1. No Profile Picture
    Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2003
    Posts
    3,604
    Rep Power
    595

    Reconciling Java and PHP MD5 Hashes


    I wasn't sure where the right place for this is but since the PHP hash function has little room for silly errors, I decided that the real issue must be in my Java method. I have a hash generated with PHP that gets passed to a Java app. The Java app then tries to reproduce that hash using the same input string so they can be compared for validation purposes. Unfortunately the resultant hashes are different. Here is the relevant code segment:
    Code:
    MessageDigest sha1=null;
    try {
    	sha1 = MessageDigest.getInstance("MD5");
    } catch (NoSuchAlgorithmException e) {
    	// TODO Auto-generated catch block
    	e.printStackTrace();
    }
    try {
    	sha1.update((memberNumber+" "+serialNumber).getBytes("UTF-8"));
    } catch (UnsupportedEncodingException e) {
    	// TODO Auto-generated catch block
    	e.printStackTrace();
    }
    byte[] hash=sha1.digest();
    System.out.println(String.format("%0"+hash.length+"x",new BigInteger(hash)));
    FWIW, the hash from PHP in is:

    2a2527858c8bd2ca6a8ef07c79581bf9

    and from Java in hex:

    6188c17bba00419cb2c03fc7d3dfd15a

    Hopefully there is someone here familiar with both PHP and Java that can see what I am doing wrong.

    Also FWIW, here is the PHP hash call:
    PHP Code:
    $key=hash("MD5",$_POST['membernumber']." ".$result[1]); 
    I have verified that the strings passed to 'hash' and 'update' are identical. TIA.
    Last edited by gw1500se; December 7th, 2012 at 09:23 AM.
    There are 10 kinds of people in the world. Those that understand binary and those that don't.
  2. #2
  3. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    Hi,

    have you compared the exact bytes of each string? This could easily be an encoding problem where the strings look the same but are in fact completely different.

    I've tested your Java code and the PHP function with the hard coded string "צה" (encoded with UTF-8), and I do get the same hash.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2003
    Posts
    3,604
    Rep Power
    595
    Thanks for the reply. I guess I am not sure what you mean. Both strings are numeric characters only (with a single intervening space) and the resulting strings look the same. I will double check the lengths to make sure there are no unprintable characters but I doubt that is it.
    There are 10 kinds of people in the world. Those that understand binary and those that don't.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2003
    Posts
    3,604
    Rep Power
    595
    Well, I'm red faced. There was a trailing new line in Java. Thanks for putting me on the right track.
    There are 10 kinds of people in the world. Those that understand binary and those that don't.
  8. #5
  9. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    By the way, that BigInteger is problematic, because the byte array is interpreted as a two's complement. If the MD5 hash starts with a 1, you'll get a "random" negative number instead of the actual hexadecimal representation.

    You could fix that by simply prepending a 0 to the by array. But I'm pretty sure there are better ways to get the hex representation of a byte array.
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2003
    Posts
    3,604
    Rep Power
    595
    It doesn't matter but thanks anyway. That println was for debugging purposes and has been removed.
    There are 10 kinds of people in the world. Those that understand binary and those that don't.

IMN logo majestic logo threadwatch logo seochat tools logo