Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java MD5 hashing not matching C# MD5 hashing

I know very little about encryption/hashing.

I have to hash an encryption key. The example in Java is like this...

String encryptionKey = "test";

    MessageDigest messageDigest = MessageDigest.getInstance("MD5");
    messageDigest.update(encryptionKey.getBytes("UTF-8"), 0, encryptionKey.length());
    byte[] encryptionKeyBytes = messageDigest.digest();

Now correct me if I'm wrong, but the above code hashes the string with the MD5 algorithm.

And I want the same result when I hash the same string in C#.

My current C# code looks like this...

string encryptionKey = "test";

        var md5 = MD5.Create();
        var keyBytes = Encoding.UTF8.GetBytes(encryptionKey);
        byte[] encryptionKeyBytes = md5.ComputeHash(keyBytes);

But the end byte results do not match.

Java gets...

[0] 9   
[1] -113    
[2] 107 
[3] -51 
[4] 70  
[5] 33  
[6] -45 
[7] 115 
[8] -54 
[9] -34 
[10]    78  
[11]    -125    
[12]    38  
[13]    39  
[14]    -76 
[15]    -10 

C# gets...

    [0] 9   byte
    [1] 143 byte
    [2] 107 byte
    [3] 205 byte
    [4] 70  byte
    [5] 33  byte
    [6] 211 byte
    [7] 115 byte
    [8] 202 byte
    [9] 222 byte
    [10]    78  byte
    [11]    131 byte
    [12]    38  byte
    [13]    39  byte
    [14]    180 byte
    [15]    246 byte

I need my C# code to get the same result as the Java code (not the other way around), any ideas?

Thank you.

like image 726
Theo Avatar asked Dec 21 '22 20:12

Theo


1 Answers

Actually, the results are identical. Like other integral types, a byte value may be interpreted as either signed or unsigned. For example, 10001111 would correspond to 143 (your second C# value) if interpreted as unsigned. However, if interpreted as signed (using two’s complement), its value would be -113 (your second Java value).

Thus, the disparity seems to be caused by your values being formatted as signed in Java but unsigned in C#. If you want to get signed bytes in C#, you can use:

sbyte[] encryptionKeyBytesSigned = 
    encryptionKeyBytes.Select(b => (sbyte)b).ToArray();

However, be careful that this is not merely a formatting issue that only arises when you display your values. When saved to file, both results should be identical.

like image 110
Douglas Avatar answered Dec 24 '22 02:12

Douglas