views:

516

answers:

2

Hi,

I have a function that generates a MD5 hash in C# like this:

MD5 md5 = new MD5CryptoServiceProvider();
byte[] result = md5.ComputeHash(data);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < result.Length; i++)
{
    sb.Append(result[i].ToString("X2"));
}
return sb.ToString();

In java my function looks like this:

MessageDigest m = MessageDigest.getInstance("MD5");
m.update(bytes,0,bytes.length);

String hashcode = new BigInteger(1,m.digest()).toString(16);
return hashcode;

While the C# code generates: "02945C9171FBFEF0296D22B0607D522D" the java codes generates: "5a700e63fa29a8eae77ebe0443d59239".

Is there a way to generate the same md5 hash for the same bytearray?

On demand:

This is the testcode in java:

File file = new File(System.getProperty("user.dir") + "/HashCodeTest.flv");
byte[] bytes = null;
try {
    bytes = FileUtils.getBytesFromFile(file);
} catch (IOException e) {
    fail();
}
try {
    generatedHashCode = HashCode.generate(bytes);
} catch (NoSuchAlgorithmException e) {
    fail();
}

and this is my code in C#

var blob = GetBlobByHttpPostedFile(httpPostedFile);
var hashCode = Md5Factory.ConvertByteArray(blob);

private static byte[] GetBlobByHttpPostedFile(HttpPostedFile httpPostedFile)
{
    var contentLength = httpPostedFile.ContentLength; 
    var result = new byte[contentLength];
    var inputStream = httpPostedFile.InputStream;
    inputStream.Read(result, 0, contentLength);

    return result;
}

Cheers

+2  A: 

That should be fine - although you could make the Java code simpler by just calling

byte[] digest = m.digest(bytes);

instead of calling update then digest.

Are you absolutely sure you've got the same data in both cases? Could you post sample programs showing this failing with the same hard-coded data?

EDIT: Here's the sort of test I was thinking of. These two programs give the same result:

C#:

using System;
using System.Security.Cryptography;
using System.Text;

class Test
{
    static void Main()
    {
        byte[] bytes = { 0x35, 0x24, 0x76, 0x12 };
        MD5 md5 = new MD5CryptoServiceProvider();
        byte[] result = md5.ComputeHash(bytes);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < result.Length; i++)
        {
            sb.Append(result[i].ToString("x2"));
        }
        Console.WriteLine(sb);
    }
}

Java:

import java.math.BigInteger;
import java.security.MessageDigest;

public class Test
{
    public static void main(String[] args) throws Exception
    {
        byte[] bytes = { 0x35, 0x24, 0x76, 0x12 };
        MessageDigest m = MessageDigest.getInstance("MD5");
        byte[] digest = m.digest(bytes);
        String hash = new BigInteger(1, digest).toString(16);
        System.out.println(hash);
    }
}
Jon Skeet
hi, yeah i'm pretty sure. I just posted the 2 functions. I'll post the programs too.
Sem Dendoncker
this is great, thx.now I'll try to find out why it doesn't work here.
Sem Dendoncker
A: 

Hi I m using this code and it works

C# code :

    public static string ConvertStringToMD5(string ClearText)
{

    byte[] ByteData = Encoding.ASCII.GetBytes(ClearText);
    //MD5 creating MD5 object.
    MD5 oMd5 = MD5.Create();
    //Hash değerini hesaplayalım.
    byte[] HashData = oMd5.ComputeHash(ByteData);

    //convert byte array to hex format
    StringBuilder oSb = new StringBuilder();

    for (int x = 0; x < HashData.Length; x++)
    {
        //hexadecimal string value
        oSb.Append(HashData[x].ToString("x2"));
    }

and Java code :

    private String getMD5Digest(byte[] buffer) {
    String resultHash = null;
    try {
        MessageDigest md5 = MessageDigest.getInstance("MD5");

        byte[] result = new byte[md5.getDigestLength()];
        md5.reset();
        md5.update(buffer);
        result = md5.digest();

        StringBuffer buf = new StringBuffer(result.length * 2);

        for (int i = 0; i < result.length; i++) {
            int intVal = result[i] & 0xff;
            if (intVal < 0x10) {
                buf.append("0");
            }
            buf.append(Integer.toHexString(intVal));
        }

        resultHash = buf.toString();
    } catch (NoSuchAlgorithmException e) {
    }
    return resultHash;
}
estergones
Note that if your string isn't entirely formed of ASCII data, you will be losing information...
Jon Skeet