Im trying to verify a webhook signature, I have this PHP code from the documentation of api2cart but I need it in Javascript.I tried however I couldn't match the signature and the HMAC generated value, more details here
steps to follow:
Gather all headers starting with “X-Webhook-” // I received it as x-webhook- in my header, don't know if it affects the encryption
Remove “X-Webhook-Signature” from the array.
Sort the headers alphabetically by the key
Encode the headers into JSON.
Concatenate the strings, JSON headers string should come first
Hash the resulting string with HMAC SHA256 function with outputs raw binary data set true (raw_output = true)
Use your store_key as a secret key to generate a binary signature
- Encode the string in Base64
$headersForJson = [
'X-Webhook-Error-Code' => '0',
'X-Webhook-Action' => 'update',
'X-Webhook-Timestamp' => '1516291592',
'X-Webhook-Entity' => 'product',
'X-Webhook-Store-Id' => '1',
'X-Webhook-Signature' => 'SGVsbG8gd2l0aCBBUEkyQ2FydA==',
];
$signatureFromRequest = $headersForJson['X-Webhook-Signature'];
unset($headersForJson['X-Webhook-Signature']);
ksort($headersForJson);
$headers = json_encode($headersForJson);
$data = $headers . $params['raw_body'];
$generatedSignature = base64_encode(hash_hmac('sha256', $data, $storeKey, true));
if (hash_equals($signatureFromRequest, $generatedSignature)) {
return true;
}
Here is what I did:
const signature = headers['x-webhook-signature'];
delete headers['x-webhook-signature'];
// the header contained other keys I had to get keys starting with x-webhooks
let xkeys = Object.keys(headers).filter(key => key.includes('x-webhook-')).sort();
let xheaders = JSON.stringify(xkeys.reduce((res, key) => Object.assign(res, { [key]: headers[key] }), {}));
let data = xheaders + rawBody
const generatedHash = createHmac('SHA256', "SecretKey")
.update(data, 'utf-8')
.digest('base64');
return generatedHash === signature
what am I missing here ?