Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

facebook webhook signature calculation (C#)

Facebook Webhooks provide a signature for each call to validate the integrity and origin of the payload but for me it is to poorly described (Facebook Webhook Reference - Security). Because of that I am having some troubles calculating the signature to validate it. So what are the steps to calculate the value?

like image 225
TomPez Avatar asked Oct 22 '25 14:10

TomPez


1 Answers

I got it working and want to share my solution (in C#) for other developers here:

    /// <summary>
    /// The HTTP request will contain an X-Hub-Signature header which contains the SHA1 signature of the request payload,
    /// using the app secret as the key, and prefixed with sha1=.
    /// Your callback endpoint can verify this signature to validate the integrity and origin of the payload
    /// </summary>
    /// <param name="appSecret">facebook app secret</param>
    /// <param name="payload">body of webhook post request</param>
    /// <returns>calculated signature</returns>
    public static string CalculateSignature(string appSecret, string payload)
    {
        /*
         Please note that the calculation is made on the escaped unicode version of the payload, with lower case hex digits.
         If you just calculate against the decoded bytes, you will end up with a different signature.
         For example, the string äöå should be escaped to \u00e4\u00f6\u00e5.
         */
        payload = EncodeNonAsciiCharacters(payload);

        byte[] secretKey = Encoding.UTF8.GetBytes(appSecret);
        HMACSHA1 hmac = new HMACSHA1(secretKey);
        hmac.Initialize();
        byte[] bytes = Encoding.UTF8.GetBytes(payload);
        byte[] rawHmac = hmac.ComputeHash(bytes);

        return ByteArrayToString(rawHmac).ToLower();
    }

    private static string EncodeNonAsciiCharacters(string value)
    {
        StringBuilder sb = new StringBuilder();
        foreach (char c in value)
        {
            if (c > 127)
            {
                string encodedValue = "\\u" + ((int)c).ToString("x4");
                sb.Append(encodedValue);
            }
            else
            {
                sb.Append(c);
            }
        }
        return sb.ToString();
    }

    private static string ByteArrayToString(byte[] ba)
    {
        string hex = BitConverter.ToString(ba);
        return hex.Replace("-", "");
    }
like image 177
TomPez Avatar answered Oct 25 '25 03:10

TomPez



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!