refactor
refactor

Reputation: 15104

generate HMAC-SHA1 in C#

I am trying to make use of a REST API using C#.

The API creator has provided below pseudo code for hmac creation.

var key1 = sha1(body);
var key2 = key1 . SECRET_KEY;
var key3 = sha1(key2);
var signature = base64_encode(key3);

In the above pseudo code , body is html request body string , and SECRET_KEY is the secret key provided by REST API provider.

As per my knowledge , I need to use System.Security.Cryptography.HMACSHA1 class to implement this.

But am not able to completely implement above logic in C#.

Any suggestions ?

Upvotes: 2

Views: 7586

Answers (2)

Mireille
Mireille

Reputation: 21

The issue to make it work in c# is that you need to take the hex format into consideration and then in some cases for it to work the final result should be lower case (example if you're using this for a quickblox api or something)

    private string GetHashedMessage(String _secret)
    {
        System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
        byte[] keyByte = encoding.GetBytes(_secret);
        String _message= "Your message that needs to be hashed";
        HMACSHA1 hmacsha1 = new HMACSHA1(keyByte);

        byte[] messageBytes = encoding.GetBytes(_message);
        byte[] hashmessage = hmacsha1.ComputeHash(messageBytes);
        return ByteToString(hashmessage).ToLower();
    }

    public string ByteToString(byte[] buff)
    {
        string sbinary = "";

        for (int i = 0; i < buff.Length; i++)
        {
            sbinary += buff[i].ToString("X2"); // hex format
        }
        return (sbinary);
    }

reference: http://billatnapier.com/security01.aspx

Upvotes: 0

Evk
Evk

Reputation: 101623

Direct mapping of above code to C# would be something like:

static string ComputeSignature(byte[] body, byte[] secret) {
    using (var sha1 = SHA1.Create())
    {
        var key1 = sha1.ComputeHash(body);
        var key2 = key1.Concat(secret).ToArray();
        var key3 = sha1.ComputeHash(key2);
        return Convert.ToBase64String(key3);
    }
}

If you have request body as a string, convert it to byte array using proper encoding, for example:

var body = Encoding.UTF8.GetBytes(bodyAsString);

If you have your secret as string - that depends on how api developer expects it to be converted to byte array. Most likely it's already HEX or base64-encoded string.

Upvotes: 2

Related Questions