Signature Key Verification
.NET
using System.Security.Cryptography;
using System.Text;
var jsonMessage = "[CALLBACK MESSAGE]";
var headers = new Dictionary<string, string>()
{
{ "X-Signature", $"sha256=yu2OvBe3Gyq1Nz/4R6KO8F3KpGCuW7VhH9yUPhYtNRU="},
{ "X-Signature-Timestamp", "1762181943494" }
};
var signature = headers.GetValueOrDefault("X-Signature")!["sha256=".Length..];
var signatureKey = "4cde378d-43b6-405f-94aa-55c010d4d42a";
var unixTimeMilliseconds = headers.GetValueOrDefault("X-Signature-Timestamp");
string message = $"{jsonMessage}.{unixTimeMilliseconds}";
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(signatureKey));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(message));
var result = Convert.ToBase64String(hash);
if (result.Equals(signature))
Console.WriteLine("Signature is valid");
else
Console.WriteLine("INVALID SIGNATURE!");.PHP
<?php
// Callback message (exact raw JSON body as string)
$jsonMessage = '[CALLBACK MESSAGE]';
// Headers received
$headers = [
'X-Signature' => 'sha256=yu2OvBe3Gyq1Nz/4R6KO8F3KpGCuW7VhH9yUPhYtNRU=',
'X-Signature-Timestamp' => '1762181943494'
];
// Extract signature and timestamp
$signatureHeader = $headers['X-Signature'];
$signature = substr($signatureHeader, strlen('sha256='));
$timestamp = $headers['X-Signature-Timestamp'];
// Merchant’s shared secret key
$signatureKey = '4cde378d-43b6-405f-94aa-55c010d4d42a';
// Build message: JSON + "." + timestamp
$message = $jsonMessage . '.' . $timestamp;
// Compute HMAC SHA256
$computedHash = hash_hmac('sha256', $message, $signatureKey, true);
// Encode to Base64
$result = base64_encode($computedHash);
// Compare (constant-time safe comparison)
if (hash_equals($result, $signature)) {
echo "Signature is valid\n";
} else {
echo "INVALID SIGNATURE!\n";
}
?>node.js
import crypto from "crypto";
// Callback message (exact raw JSON string)
const jsonMessage = "[CALLBACK MESSAGE]";
// Headers received
const headers = {
"X-Signature": "sha256=yu2OvBe3Gyq1Nz/4R6KO8F3KpGCuW7VhH9yUPhYtNRU=",
"X-Signature-Timestamp": "1762181943494",
};
// Extract signature and timestamp
const signatureHeader = headers["X-Signature"];
const signature = signatureHeader.substring("sha256=".length);
const timestamp = headers["X-Signature-Timestamp"];
// Shared secret key
const signatureKey = "4cde378d-43b6-405f-94aa-55c010d4d42a";
// Build message: JSON + "." + timestamp
const message = `${jsonMessage}.${timestamp}`;
// Compute HMAC SHA256
const hmac = crypto.createHmac("sha256", signatureKey);
hmac.update(message, "utf8");
const computedSignature = hmac.digest("base64");
// Constant-time comparison
if (crypto.timingSafeEqual(Buffer.from(computedSignature), Buffer.from(signature))) {
console.log("Signature is valid");
} else {
console.log("INVALID SIGNATURE!");
}Last updated