1

I'm working with gocardless hooks , and i'm stuck on validating hmac signature with sandbox environment.

So I generated webhook test in sandbox and it gives to me the request body and headers as it has sent.

So as far as i understand , i must get the request body and generate a hash with secret key , and compare it with the webhook signature header hash ( not sounds really complicated ) .

So i'm using postman to reproduce it in my local environment, attaching the equal headers and the same body , but signature never match.

Here is what i tried :

 $signature = hash_hmac('sha256',$request->getContent(), 'secret');

Notice i'm using laravel framework , so my first thinking was maybe the framework is manipulating internally the request , so i tried this :

 $request_data = file_get_contents('php://input');
 $signature = hash_hmac('sha256',$request_data, 'secret');

But still doesn't match , i noticed meany new lines and maybe this could modify the results so i cleaned it ...

 $request_data = str_replace(array('.', ' ', "\n", "\t", "\r"), '', $request_data);

But still not match , and also i tried to cast body data in utf8 , and making hmac returning raw and encoding it in base64 ... but no success.

So what can be wrong here? Maybe signatures not working in sandbox environment? Has anyone dealed with it ?

Thank's in advance!

Joaquin Javi
  • 880
  • 7
  • 12

2 Answers2

2

Finally i found the issue , in the sandbox panel in goocardless they show the request unminified , so the length is different , just minify it and you will be able to test ! and now signatures matches!

Joaquin Javi
  • 880
  • 7
  • 12
  • Could you please clarify what you mean by unminified? Maybe an example could be useful. – gdvalderrama Nov 03 '16 at 10:41
  • I was copy pasting the goocardless webhook sent object to postman and sending it to my endpoint to simulate receiving webhooks, in the GC panel test webhook response is shown idented ( for better reading purposes ), and signature didn't match because the length will be different, they send minified request meaning no white spaces! – Joaquin Javi Nov 03 '16 at 13:23
  • 1
    Got it, thanks. I thought you meant there were also line breaks or such things. It helps to know there should be no white spaces at all though. – gdvalderrama Nov 03 '16 at 17:12
  • You welcome ! I know it's sounds silly ... But it took me couple of hours to realize what was going wrong! – Joaquin Javi Nov 03 '16 at 17:47
1

We've updated our developer documentation and you can find an example of verifying webhook signature over at https://developer.gocardless.com/getting-started/api/staying-up-to-date-with-webhooks/?lang=php#building-a-webhook-handler

You want to do something like

<?php
// We recommend storing your webhook endpoint secret in an environment variable
// for security, but you could include it as a string directly in your code
$token = getenv("GC_WEBHOOK_SECRET");

$raw_payload = file_get_contents('php://input');

$headers = getallheaders();
$provided_signature = $headers["Webhook-Signature"];

$calculated_signature = hash_hmac("sha256", $raw_payload, $token);

if ($provided_signature == $calculated_signature) {
  // Process the events

  header("HTTP/1.1 200 OK");
} else {
  header("HTTP/1.1 498 Invalid Token");
}
Andrew Farrell
  • 2,368
  • 2
  • 22
  • 25