'Verifying Qb notification signature in C#
I am trying to verify signature , I received from QB notification but always failing. Below is my function I made
public static bool ValidateRequest(Dictionary<string, string> headers, string payload, string verifier)
{
string signature = headers["intuit-signature"];
if ((signature == null))
{
return false;
}
try
{
byte[] secretKeyBArr = Encoding.UTF8.GetBytes(verifier);
byte[] dataBytes = Encoding.UTF8.GetBytes(payload);
HMACSHA256 hmacsha256 = new HMACSHA256();
hmacsha256.Key = secretKeyBArr;
hmacsha256.Initialize();
byte[] hmacBytes = hmacsha256.ComputeHash(dataBytes);
string hash = Convert.ToBase64String(hmacBytes);//Payload value
return hash.Equals(signature);
}
catch (Exception ex)
{
throw ex;
}
return false;
}
Not sure why computed signature and received signature does not match all time.
Appreciate your inputs.
Solution 1:[1]
If your having the same issue I had, its because of the way I was serializing the payload. When QBO generates the signature, they use datetimes in the format 2022-05-11T15:11:58.000Z. I was serializing it as 2022-05-11T15:11:58Z
I considered 2 options
help with serialization:
public class QboChangeEventEntitiesVm
{
[Required]
[JsonProperty(PropertyName = "name")]
public string? Name { get; set; }
[Required]
[JsonProperty(PropertyName = "id")]
public string? Id { get; set; }
[Required]
[JsonConverter(typeof(StringEnumConverter))]
[JsonProperty(PropertyName = "operation")]
public QboOperationType? Operation { get; set; }
[JsonConverter(typeof(DateFormatConverter), "yyyy-MM-dd'T'HH:mm:ss.fff'Z'")]
[JsonProperty(PropertyName = "lastUpdated")]
public DateTime? LastUpdated { get; set; }
}
public class DateFormatConverter : IsoDateTimeConverter
{
public DateFormatConverter(string format)
{
DateTimeFormat = format;
}
}
or just retrieve the raw bits
string requestBody;
using (var stream = new MemoryStream())
{
var context = (HttpContextBase)Request.Properties["MS_HttpContext"];
context.Request.InputStream.Seek(0, SeekOrigin.Begin);
context.Request.InputStream.CopyTo(stream);
requestBody = Encoding.UTF8.GetString(stream.ToArray());
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | user3161312 |