Search code examples
javascriptc#hashmd5asciiencoding

Generate Base64 MD5 hash of byte array


I have following security encoding implemented in my c# web api:

string testStr = "test";
ASCIIEncoding encoding = new ASCIIEncoding();    //using System.Text;
byte[] byteData = encoding.GetBytes(testStr);

MD5 md5 = MD5.Create();    //using System.Security.Cryptography;
string hash = md5.ComputeHash(byteData);
string md5Base64 = Convert.ToBase64String(hash);

I bind this md5Base64 string in header and compare it in API request. This works fine when I hit the API from C# code. Now I need to use it in javascript, so will need js equivalent of above code.

I have tried following but it is giving different output:

var testStr = 'test';
var byteData = testStr.split ('').map(function (c) { return c.charCodeAt (0); });
var hash = MD5(value.join(','));
var md5Base64 = btoa(hash);

the MD5 function used here is from https://stackoverflow.com/a/33486055/7519287

Please let me know what is wrong here.


Solution

  • The problem with your JavaScript code is that you're doing unnecessary conversions: MD5 already takes a string. Furthermore, more conversions after hashing are required.

    If we have the following C# code:

    string tmp = "test";
    byte[] bTmp = System.Text.Encoding.UTF8.GetBytes(tmp);
    byte[] hashed = null;
    using (System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider())
    {
        hashed = md5.ComputeHash(bTmp);
    }
    
    Console.WriteLine(Convert.ToBase64String(hashed));
    

    Fiddle

    then the equivalent JavaScript code is:

    var tmp = 'test';
    var hashed = hex2a(MD5(tmp)); // md5 src: https://stackoverflow.com/a/33486055/7519287
    
    // src: https://stackoverflow.com/a/3745677/3181933
    function hex2a(hexx) {
        var hex = hexx.toString();//force conversion
        var str = '';
        for (var i = 0; i < hex.length; i += 2)
            str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
        return str;
    }
    
    alert(btoa(hashed));
    

    Fiddle

    Because MD5 returns a hex string, you have to convert that to ASCII before you can base64 encode it. I wonder if you need base64 encoding? MD5 is usually represented as a hex string. Perhaps on the C# side, instead of Convert.ToBase64String(hashed), you could use BitConverter.ToString(hashed).Replace("-", "") to get a hex string for the MD5 hash? Then you could simply just use MD5(tmp) in JavaScript.