tags:

views:

636

answers:

3

Hi everybody,

I'm facing kind of a strange issue which is related MD5-Hashes in Java and php5. I figured that unter certain circumstances the following code does not generate correct MD5 hashes:

public static String getMD5Hash(String string)
{
 try 
 {
  MessageDigest md5 = MessageDigest.getInstance("MD5");
  md5.update(string.getBytes());
  byte[] digest = md5.digest();

  string = byteArrToHexString(digest);
 } 
 catch (NoSuchAlgorithmException e1) 
 {
  e1.printStackTrace();
 }

 return string;
}

private static String byteArrToHexString(byte[] bArr)
{
 StringBuffer sb = new StringBuffer();

 for (int i = 0; i < bArr.length; i++) 
 {
  int unsigned = bArr[i] & 0xff;
  sb.append(Integer.toHexString((unsigned)));
 }

 return sb.toString();
}

I had to migrate an existing user database where the passwords where stored in php5 MD5. Now some of the users, not all, can't login because my Java code does not produce the correct MD5 hash.

Any ideas what's wrong with the above?

A: 

You are missing:

md5.reset();

before doing an update()

Check Java md5 example with MessageDigest

Macarse
Should not be an issues since a new MessageDigest object is being created each time. You would need to reset if you were reusing the same object over and over again.
laalto
Added this, no result. Thx anyways!
+7  A: 

byteArrToHexString does not convert bytes <0x10 correctly, you need to pad them with zeros.

Example:

int unsigned = bArr[i] & 0xff;
if (unsigned < 0x10)
  sb.append("0");
sb.append(Integer.toHexString((unsigned)));
laalto
beat me to it :P nice work
Marc Towler
Sry, could you give me a snippet of that one? Did'nt get it right I'm afraid.
Edited to add padding example.
laalto
Thx laalto, that one worked out.
+1  A: 

So funny... I just encountered a problem with MD5 hashed passwords myself. The problem in my case was the encoding of the original password into a byte[].

I advise you to find out exactly which encoding was used to hash the passwords previously, and change line 6 of the code above to

md5.update(string.getBytes("UTF-8"));

(Of course, this is just an example... find out the correct Charset to use as a parameter)

BTW, I suppose you have your reasons, but why not have the hashing method do this?

return new String(digest, "UTF-8");

Yuval =8-)

Yuval