Wednesday, July 16, 2008

watch out - md5 sum bug

The other day I was in for a rude surprise when it was reported that in the application which we had developed, the authentication at times fails. The application required to auto generate an md5 encrypted value for authentication and it was found that md5 value generated was dropping the leading zero's when ever the actual md5 sum value was supposed to have leading zero's.

It was a rude shock for me.

This was the piece of code that I had,

String unencryptedValue= "test"; MessageDigest m= MessageDigest.getInstance("MD5"); m.update(unencryptedValue.getBytes(),0,unencryptedValue.length());
String encryptedValue = new BigInteger(1,m.digest()).toString(16);

Then it took me some time to realize that the BigInteger casting was causing the havoc, and at the same time waruna gave me a link to the following blog http://jdwyah.blogspot.com/2006/08/java-md5-password-hash.html, which has the solution for the above problem,

its just a matter of introducing another method which would pad the leading zero's to the md5 value to make up the required length.

the fixed code looked something like below,

String unencryptedValue= "test"; MessageDigest m= MessageDigest.getInstance("MD5"); m.update(unencryptedValue.getBytes(),0,unencryptedValue.length());
String encryptedValue = new BigInteger(1,m.digest()).toString(16);
encryptedValue = fixLeadingZeroBug(encryptedValue, 32, '0');

public String fixLeadingZeroBug(String s, int length, char pad) { StringBuffer buffer = new StringBuffer(s); while (buffer.length() <> buffer.insert(0, pad); } return buffer.toString(); }

It was just now a matter of fixing the bug and instead I learnt an important lesson to be a mindful of these leading zero's when ever an integer is used in place of having it as a String for intermediate processing. But unfortunately I had to learn it the hard way. :(