0

I am trying to use Webhook and validating using HMAC in webapi with target framework 4.6.2, but it is failed. I am doing like this. In post method I have this validateHMAC method and rest of the code process is below

    bool  isvalid = ValidateHMAC();

     private bool ValidateHMAC()
    {
        string hmacSignature1 = string.Empty;
        System.Net.Http.Headers.HttpRequestHeaders headers = Request.Headers;
        if (headers.Contains("X-DocuSign-Signature-1"))
        {
            hmacSignature1 = headers.GetValues("X-DocuSign-Signature-1").First();
        }

        string requestFromPost = string.Empty;

        using (StreamReader reader = new StreamReader(HttpContext.Current.Request.InputStream))
        {
            reader.BaseStream.Position = 0;
            requestFromPost = reader.ReadToEnd();
        }

        return HashIsValid(requestFromPost, hmacSignature1);
    }
    private string ComputeHash(string payload)
    {
        string docuSignHMACSecretKey = "KXXXXKXXKXKXKXXXX-FFDocuSignHMACKey"; //LIKE THIS
        byte[] bytes = Encoding.UTF8.GetBytes(docuSignHMACSecretKey);
        System.Security.Cryptography.HMAC hmac = new System.Security.Cryptography.HMACSHA256(bytes);
        bytes = Encoding.UTF8.GetBytes(payload);
        bytes = hmac.ComputeHash(bytes);
        var computedHash = Convert.ToBase64String(bytes);
        return computedHash;
    }
    private bool HashIsValid(string payload, string verify)
    {
        var hashOutput = ComputeHash(payload).Equals(verify);
        return hashOutput;
    }

1 Answers1

0

Try this code instead:

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

public static class HMACValidation
{
    public static string ComputeHash(string secret, string payload)
    {
    byte[] bytes = Encoding.UTF8.GetBytes(secret);
    HMAC hmac = new HMACSHA256(bytes);
    bytes = Encoding.UTF8.GetBytes(payload);

    return Convert.ToBase64String(hmac.ComputeHash(bytes));
    }




    public static bool HashIsValid(string secret, string payload, string verify)
    {

    ReadOnlySpan<byte> hashBytes = Convert.FromBase64String(ComputeHash(secret, payload));
    ReadOnlySpan<byte> verifyBytes = Convert.FromBase64String(verify);

    return CryptographicOperations.FixedTimeEquals(hashBytes, verifyBytes);
    }
}
Inbar Gazit
  • 12,566
  • 1
  • 16
  • 23
  • I have tried this but CryptographicOperations.FixedTimeEquals is not in webapi 2 i.e framework 4.7.2 as it is in 5.0 and I can't update to this version. – Shyam Vashista Nov 15 '21 at 12:53
  • ok, but if you just do regular comparison? it still doesn't work? does it just say the strings are different all the time? – Inbar Gazit Nov 15 '21 at 16:15
  • Yes it never match both strings. defined in connect setting and convert using HMAC – Shyam Vashista Nov 16 '21 at 08:36
  • Hi Inbar Gazit, any update on this? any way to make in framework 4.7.2 ? – Shyam Vashista Nov 18 '21 at 10:08
  • You may have to contact our support engineers. The issue is not related to what framework you're using. I am not sure why you don't get the same key back. Potentially you are not copying the key correctly and getting it from the right account or something like that, I dont' know and can't help you over here. – Inbar Gazit Nov 18 '21 at 15:14