Crypto.HMAC issues

Already shared in the last post, you could use that for the current payload as that was received as test and i stored those values

Im not talking about the payload


So where is your “everything after sha256=” from the header you check?
The part you generate (the hash) and compare (the above) must match. If your comparison from the header includes wrong data you get incorrect match.

Yeah we need to see your code for extracting the values from the request. I thought you shared that already, but I’m not seeing it.

considering that i already validated that i thought that it is clear , that would be my code of getting the payload from the Request, as recommended i got just the body and that is the only thing i get , just the JSON

Var payload As String = Request.Body

FWIW, I took the JavaScript code you posted above and ran it against my own values, then compared the result to Xojo. They are identical.

const crypto = require("crypto")

function verifyRequestSignature(buf, secret) {
  var expectedHash = crypto
    .createHmac("sha256", secret)
    .update(buf)
    .digest("hex");
  console.log(expectedHash);
}

verifyRequestSignature("hi", "somesecret")

Xojo:

var raw as string = Crypto.HMAC( "somesecret", "hi", Crypto.HashAlgorithms.SHA2_256 )
var encoded as string = EncodeHex( raw ).Lowercase

The result from both is:

1fcfb8e3c21ec4362d78cc10951a7a08ed1824c6297fb39790a2f40708e5bbe0

No expert here, but these look different.

1 Like

They aren’t. The former was replaced by the latter, but both still work.

However, just to confirm, I tried it with the old style and there is no difference.

2 Likes

“Replaced” was the wrong word there. If you look at the Crypto.HashAlgorithms enum, both values appear. The new style is the one I posted in my code, but both work.

1 Like

Thanks. Good to know they work the same.

hmm, so what could be on my side then ? did you tried using my data, as now you have the key ? and see if you get same ? it would be worth to check my data in your JS as well and see if you get same, as something is wrong here. @AlbertoD the docs require SHA_256 however XOJO has both so i did not tested the second

If you post the payload as text, or direct me to it, I will be happy to test.

My first post has the Signature; payload where you need to remove payload : and , here is the key for all that “ywLwFaCyD9DyGHWsDP2uUPnpH3KwaQ” . Now looking at the docs Webhooks Setup - WhatsApp Business Management API - Documentation - Meta for Developers it does say something interesting

All notifications have the following generic format:

[{
“object”: “whatsapp_business_account”,
“entry”: [{
“id”: “{whatsapp-business-account-id}”,
“time”: {unix-timestamp},
“changes”: [{
“field”: “{subscribed-field}”,
“value”: {
# Information that was update
}
}]
}]
}] while if you see my payload what i get from them starts with { instead of [ so not sure here if the documentation is old or something is bad, but so far that is the only data i get from the API, and if i press on the test webhook that is the sample data that it sends

{
“field”: “message_echoes”,
“value”: {
“messaging_product”: “whatsapp”,
“metadata”: {
“display_phone_number”: “16505551111”,
“phone_number_id”: “123456123”
},
“message_echoes”: [
{
“from”: “16315551181”,
“to”: “11234567890”,
“id”: “ABGGFlA5Fpa”,
“timestamp”: “1504902988”,
“type”: “text”,
“text”: {
“body”: “this is a text message”
}
}
]
}
}

Using the JavaScript code, I can’t get a match to the given signature in your first post.

EDIT: I just realized the posted text has curly quotes. Let me straighten and try again.

my webapp on HandleURL just checks for Request.Method and if that is a POST then it prints the data , so this is how the code looks

Case "POST"
  ' Handle the incoming POST request for webhook events
  If Request.Body <> "" Then
    Var payload As String = Request.Body
    
    ' Extract the signature from the headers
    Var signature256 As String = Request.Header("X-Hub-Signature-256").NthField("=", 2)
    
    log2File("signature256  : " + signature256)
    
    log2File("payload  : " + payload)
    
    
    ' Generate the SHA256 HMAC
    'Var payloadMB As MemoryBlock = payload
    Var payloadMB As MemoryBlock = payload
    Var hmac As MemoryBlock = Crypto.HMAC(wpT, Request.Body, Crypto.HashAlgorithms.SHA256)
    Var hmacString As String = hmac.StringValue(0, hmac.Size)
    Var generatedSignature As String = EncodeHex(hmacString).Lowercase
    
    log2File("hmacString  : " + hmacString)
    log2File("generatedSignature  : " + generatedSignature)

In my case i don’t do any processing for the Request.Body and i take only what i receive , now , is it possible that XOJO does some trimming in the Request side ?

No matter what I’ve tried, I cannot get the JS code to generate the same hash as in your original post. That includes:

  • Adding a linefeed before the json.
  • Adding a linefeed after the json.
  • Adding linefeeds before and after json.
  • Wrapping the json in square brackets.
  • Decoding the secret from Base64, in case it was encoded.

I can get it to match the hash you generated from Xojo as in your original post.

Conclusion: it’s not your Xojo code that’s the issue, it’s a mismatch in the secret key or the incoming data, or an error on the sender’s side.

Thanks a lot Kem, i guess i need to write to them, and even if they don’t make this mandatory they do recommend to use it, but apparently it seems that this does not work for some reason so maybe they updated something but they forgot to mention it . I do see that they have a SHA1 as well so i will try to see maybe that part matches only , then in this case i will use just that .

Thanks again