Saeid
Saeid

Reputation: 13592

Ignore Zero in Calculate Hash by HMACSHA256

I use Crypto-JS v2.5.3 (hmac.min.js) http://code.google.com/p/crypto-js/ library to calculate client side hash and the script is:

$("#PasswordHash").val(Crypto.HMAC(Crypto.SHA256, $("#pwd").val(), $("#PasswordSalt").val(), { asByte: true }));

this return something like this:

b3626b28c57ea7097b6107933c6e1f24f586cca63c00d9252d231c715d42e272

Then in Server side I use the following code to calculate hash:

private string CalcHash(string PlainText, string Salt) {
        string result = "";
        ASCIIEncoding enc = new ASCIIEncoding();
        byte[]
        baText2BeHashed = enc.GetBytes(PlainText),
        baSalt = enc.GetBytes(Salt);
        System.Security.Cryptography.HMACSHA256 hasher = new HMACSHA256(baSalt);
        byte[] baHashedText = hasher.ComputeHash(baText2BeHashed);
        result = string.Join("", baHashedText.ToList().Select(b => b.ToString("x")).ToArray());
        return result;
    }

and this method returned:

b3626b28c57ea797b617933c6e1f24f586cca63c0d9252d231c715d42e272

As you see there is just some zero characters that the server side method ignore that. where is the problem? is there any fault with my server side method? I just need this two value be same with equal string and salt.

Upvotes: 1

Views: 316

Answers (3)

Sani Huttunen
Sani Huttunen

Reputation: 24395

I believe the problem is here:

result = string.Join("", baHashedText.ToList().Select(b => b.ToString("x")).ToArray());

change it to:

result = string.Join("", baHashedText.ToList().Select(b => b.ToString("x2")).ToArray());

Upvotes: 1

Scott Chamberlain
Scott Chamberlain

Reputation: 127603

Everyone else keeps reccomending to use things like using BitConverter and trimming "-" or using ToString(x2). There is a better solution, a class that has been in .NET since 1.1 SoapHexBinary.

using System.Runtime.Remoting.Metadata.W3cXsd2001;

public byte[] StringToBytes(string value)
{
    SoapHexBinary soapHexBinary = SoapHexBinary.Parse(value);
    return soapHexBinary.Value;
}

public string BytesToString(byte[] value)
{
    SoapHexBinary soapHexBinary = new SoapHexBinary(value);
    return soapHexBinary.ToString();
}

This will produce the exact format you want.

Upvotes: 2

Jon Skeet
Jon Skeet

Reputation: 1503649

As you see there is just some zero characters that the server side method ignore that. where is the problem?

Here - your conversion to hex in C#:

b => b.ToString("x")

If b is 10, that will just give "a" rather than "0a".

Personally I'd suggest a simpler hex conversion:

return BitConverter.ToString(baHashedText).Replace("-", "").ToLowerInvariant();

(You could just change "x" to "x2" instead, to specify a length of 2 characters, but it's still a somewhat roundabout way of performing a bytes-to-hex conversion.)

Upvotes: 4

Related Questions