Having Trouble Validating Webhook

Hi,

I’m trying to verify my webhook vai c# and it is not working. Can I please get some assistance on my code to see where I’m going wrong?

Thank you.

       log.Info("Recieved validation request");
        JObject joPayload = JObject.Parse(payload);
        var keySent  = (string)joPayload.SelectToken("payload.plainToken");
        log.Info("Key Sent: " + keySent);

        string hashString = "";
        var secret = keySent;
        var message = keySent;
        var encoding = new System.Text.ASCIIEncoding();
        byte[] keyByte = encoding.GetBytes(secret);
        byte[] messageBytes = encoding.GetBytes(message);
        using (var hmacsha256 = new HMACSHA256(keyByte))
        {
            byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
            hashString = Convert.ToBase64String(hashmessage);
        }

        StringBuilder sb = new StringBuilder();
        foreach (char t in hashString)
        { 
            //Note: X for upper, x for lower case letters
            sb.Append(Convert.ToInt32(t).ToString("x2")); 
        }

        response = "{\"plainToken\": \"" + keySent +"\",\"encryptedToken\": \"" + hashString + "\"}";
        log.Info("Response: " + response);

Hi @ahavatammi
Thanks for reaching out!
Have you been able to troubleshoot this? or do you still need assistance here?
I will take a look into this in the meantime!
Best,
Elisa

Hi Elisa,

Yes, can I please get some assistance? I have read many articles and still am unable to get this to work.

Thank you,
Jeff

Hi @ahavatammi
Here is a code snippet that might be helpful

const crypto = require('crypto')

const message = `v0:${request.headers['x-zm-request-timestamp']}:${JSON.stringify(request.body)}`

const hashForVerify = crypto.createHmac('sha256', ZOOM_WEBHOOK_SECRET_TOKEN).update(message).digest('hex')

const signature = `v0=${hashForVerify}`

if (request.headers['x-zm-signature'] === signature) {
  // Webhook request came from Zoom
} else {
  // Webhook request did not come from Zoom
}

And also the link to our sample app

Note how you would have to construct a message string first and then you would pass that message down to validate the URL

Hope this helps

Hi Elisa,

Thank you for the code sample.

I was able to figure it out with the help of Free HMAC-SHA256 Online Generator Tool | Devglan. I used it to the create the return value and then compare it to my code.

Here is a working example for those coming behind me.

        private static string UrlValidation(string sig, string tStamp, string payload, ILogger log)
        {

            log.LogInformation("Recieved validation request");

			// get the plainToken
            JObject joPayload = JObject.Parse(payload);
            var plainToken = (string)joPayload.SelectToken("payload.plainToken");
            log.LogInformation("plainToken: " + plainToken);

            // secret token from the marketplace app
            string secretToken = "<your token here>";

            string message = plainToken;
            
            // convert secret token to bytes
            byte[] secretTokenByte = new UTF8Encoding().GetBytes(secretToken);
            // convert the plainToken sent in to bytes
            byte[] messageBytes = new UTF8Encoding().GetBytes(message);
            // hash it
            byte[] hashmessage = new HMACSHA256(secretTokenByte).ComputeHash(messageBytes);
            // to lowercase hex
            string hexMessage = String.Concat(Array.ConvertAll(hashmessage, x => x.ToString("x2")));
            // create return message
            string response = "{\"plainToken\": \"" + plainToken + "\",\"encryptedToken\": \"" + hexMessage + "\"}";

            log.LogInformation("Response: " + response);

            return response;
        }

Hi @ahavatammi
Thanks for sharing your findings with the community!
Feel free to reach out back to us if you need anything else!
Best,
Elisa

I did try with UrlValidation function which is provided in the sample code, it returns the value which is not same as the x-zm-signature value. Am I missing anything?

@ahavatammi , I’m not seeing plainToken in the payload object. How did you get that value?