Why is the signature not computing correctly?

Hello. All of my code works properly if I ignore using the signature, so something in the following isn’t correct. Please advise.

$requestBody = file_get_contents('php://input');
$requestHeaders = getallheaders();

$squareSignature = $requestHeaders['X-Square-Hmacsha256-Signature'] ?? '';

if (!$squareSignature) {
    http_response_code(400);
    error_log('Missing Signature');
    exit;
}

$config = parse_ini_file('/home/XYZ/XYZConfig.ini', true);
$webhookSignatureKey = $config['background_payment']['webhookSignatureKey'];

function verifySquareSignature($webhookSignatureKey, $squareSignature, $requestBody)
{
    $decodedSignature = base64_decode($squareSignature);

    $calculatedSignature = hash_hmac('sha256', $requestBody, $webhookSignatureKey, true);  

    return hash_equals($decodedSignature, $calculatedSignature);
}

if (!verifySquareSignature($webhookSignatureKey, $squareSignature, $requestBody)) {
    http_response_code(403); // Forbidden
    error_log('Invalid Signature');
    exit;
}

:wave: I’m Square Dev AI, here to help answer your question!
Based on the information you’ve provided, the following documentation will help answer your question:

Additional Documentation

Using the Square PHP SDK
Square PHP SDK Quickstart
Using the REST API

If this documentation helped you find a solution, please check the box indicating that this reply solves the problem.
Otherwise one of our Developer Advocates will provide additional assistance shortly.

The code you’ve provided seems to be correct for verifying the webhook signature. However, there are a few things you might want to check:

  1. Ensure that the webhookSignatureKey you’re using is correct. This should be the webhook signature key associated with the webhook you’re trying to verify.

  2. Make sure that the X-Square-Hmacsha256-Signature header is being sent with the request. This is the signature you’re trying to verify.

  3. Check that the requestBody is being read correctly. This should be the raw body of the request, not parsed or altered in any way.

  4. The hash_equals function used in the verifySquareSignature function is binary safe, but make sure that both inputs are of the same type. In this case, both should be binary strings.

If you’ve checked all of these and are still having issues, it might be helpful to log the values of webhookSignatureKey, squareSignature, and requestBody to ensure they’re what you expect.

This answer was reviewed by @Bryan-Square.

The correct header is: X-Square-Hmacsha256-Signature (which is what you said, but X-Square-HmacSha256-Signature is in the documentation). Thank you. This is resolved.

I spoke too soon. The issue persists. I was able to get the signature to be verified using the following code, but I want to avoid vendor.

require ‘/home/XYZ/vendor/autoload.php’;
use Square\Utils\WebhooksHelper;

define(“NOTIFICATION_URL”, “https://XYZ.com/Professionals/BackgroundCheck/SquareWebhook.php”);

$config = parse_ini_file(‘/home/shyftdog/XYZConfig.ini’, true);
define(“SIGNATURE_KEY”, $config[‘background_payment’][‘webhookSignatureKey’]);

$headers = getallheaders();
//Not ‘X-Square-HmacSha256-Signature’
if (!isset($headers[‘X-Square-Hmacsha256-Signature’])) {
error_log(‘Missing X-Square-Hmacsha256-Signature header’);
http_response_code(400);
exit;
}

$signature = $headers[‘X-Square-Hmacsha256-Signature’];

$body = file_get_contents(‘php://input’);

if (WebhooksHelper::isValidWebhookEventSignature($body, $signature, SIGNATURE_KEY, NOTIFICATION_URL)) {
http_response_code(200);

$data = json_decode($body, true);
if (json_last_error() !== JSON_ERROR_NONE) {
http_response_code(400); // Bad Request
error_log('Webhook JSON Decode Error: ’ . json_last_error_msg());
exit();
}
} else {
http_response_code(403);
error_log(“Invalid Signature”);
}