4

in the last 5 hours im trying to do something that should be very simple and did it in like 10 minutes in C#, but no luck with Java. I got a 32 UpperCase and Numeric String (A-Z0-9), I need to convert this String to Dec, and then md5 it. My problem is that I dont have unsgined bytes so I cant md5 my array :\

Here is what I need to do in python:

salt = words[1].decode("hex")
passwordHash = generatePasswordHash(salt, pw)
generatePasswordHash(salt, password):
    m = md5.new()
    m.update(salt)
    m.update(password)
    return m.digest()

and here it is in C# :

public static string GeneratePasswordHash(byte[] a_bSalt, string strData) {
    MD5 md5Hasher = MD5.Create();

    byte[] a_bCombined = new byte[a_bSalt.Length + strData.Length];
    a_bSalt.CopyTo(a_bCombined, 0);
    Encoding.Default.GetBytes(strData).CopyTo(a_bCombined, a_bSalt.Length);

    byte[] a_bHash = md5Hasher.ComputeHash(a_bCombined);

    StringBuilder sbStringifyHash = new StringBuilder();
    for (int i = 0; i < a_bHash.Length; i++) {
        sbStringifyHash.Append(a_bHash[i].ToString("X2"));
    }

    return sbStringifyHash.ToString();
}

protected byte[] HashToByteArray(string strHexString) {
    byte[] a_bReturn = new byte[strHexString.Length / 2];

    for (int i = 0; i < a_bReturn.Length; i++) {
        a_bReturn[i] = Convert.ToByte(strHexString.Substring(i * 2, 2), 16);
    }

    return a_bReturn;
}

I will be very happy to get a help with this :)

Gray
  • 115,027
  • 24
  • 293
  • 354

3 Answers3

11

To parse a hex string into a byte : (byte) Integer.parseInt(s, 16).

To transform your password string into a byte array, using the default encoding (which I suggest not to do : always specify a specific encoding) : password.getBytes() (or password.getBytes(encoding) for a specific encoding).

To hash a byte array : MessageDigest.getInstance("MD5").digest(byte[]).

To transform a byte to a hex String : See In Java, how do I convert a byte array to a string of hex digits while keeping leading zeros?

Community
  • 1
  • 1
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Already tried all of the above, didnt work out as unsigned byte of 246 becomes a -10 and it changes my final hash. –  Oct 28 '11 at 15:31
  • a byte is a byte. Whether it's considred as a negative number or a positive one doesn't change its internal sequence of bits. It shouldn't change your final hash. Why don't you show us your Java code? – JB Nizet Oct 28 '11 at 15:34
  • http://pastebin.com/q41uYJL4 - as you can see, I figured that out and its working as suppose to :) Thanks for the help. –  Oct 28 '11 at 15:49
2

I believe that something like the following will work:

// convert your hex string to bytes
BigInteger bigInt = new BigInteger(salt, 16);
byte[] bytes = bigInt.toByteArray();
// get the MD5 digest library
MessageDigest md5Digest = null;
try {
    md5Digest = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
    // error handling here...
}
// by default big integer outputs a 0 sign byte if the first bit is set
if (bigInt.testBit(0)) {
    md5Digest.update(bytes, 1, bytes.length - 1);
} else {
    md5Digest.update(bytes);
}
// get the digest bytes
byte[] digestBytes = md5Digest.digest();

Here's more ideas for converting a hex string to a byte[] array:

Community
  • 1
  • 1
Gray
  • 115,027
  • 24
  • 293
  • 354
  • Similar solution for SHA-1: http://stackoverflow.com/questions/4332740/sha1-hash-on-hex-string – Gray Oct 28 '11 at 15:13
  • Take a look at here please, http://pastebin.com/gxFT55rt - I wrote what the results should be as I tested it in my working Python app. –  Oct 28 '11 at 15:30
  • Already figured that out ad you can see above, thanks for the help anyway. –  Oct 28 '11 at 16:05
  • The problem with my code was that BigInteger adds a leading byte 0 at the front if first character has the high bit set. I've fixed it now. – Gray Oct 28 '11 at 16:31
0

You can use unsigned numbers in java with applying bit masks. Take a look details here.

mishadoff
  • 10,719
  • 2
  • 33
  • 55