Webhook Authentication
We ensure the security and integrity of webhook calls through HMAC (Hash-based Message Authentication Code) authentication. This method verifies the authenticity of incoming requests and protects against tampering.
How HMAC Authentication Works
-
Secret Key: Both the sender (Credit App) and receiver (your application) share a secret key which is your API key.
-
Creating the Signature:
- When sending a webhook request, Credit App will calculate the HMAC of the request payload using the secret key and the hashing algorithm (SHA-256). This digest is converted to a hexadecimal string.
- This generates a unique signature specific to the payload and the secret key.
-
Including the Signature:
- The calculated signature is added to the request header using the header key
X-Credit-App-Signature
to store the signature value.
- The calculated signature is added to the request header using the header key
-
Server Verification:
- When your server receives a webhook request, it should calculate the HMAC of the received payload using its secret key and the same hashing algorithm.
-
Comparing Signatures:
- The value to the calculated HMAC signature should be compared to the one received in the in the request header.
- If the two signatures match, the request is considered authentic and untampered.
Example Webhook Request with Signature
const crypto = require('crypto');
// Secret key shared between sender and receiver (API KEY)
const secretKey = 'my_secret_key';
// Original data
const data = 'Hello, this is the data to protect.';
// Calculate HMAC
const hmac = crypto.createHmac('sha256', secretKey);
hmac.update(data);
const calculatedHmac = hmac.digest('hex');
// Appending HMAC to data
const protectedData = {
X-CREDIT-APP-SIGNATURE: calculatedHmac,
body: data,
};
// Simulating sending data over the network...
// Simulating receiving data
const receivedData = protectedData;
// Separate data and received HMAC
const receivedHmac = receivedData.X-CREDIT-APP-SIGNATURE; //this will be in the headers of the request
const receivedDataOnly = receivedData.body;
// Recreate HMAC
const recreatedHmac = crypto
.createHmac('sha256', secretKey)
.update(receivedDataOnly)
.digest('hex');
// Compare HMACs
if (receivedHmac === recreatedHmac) {
console.log('Data is authentic and not tampered.');
} else {
console.log('Data has been tampered.');
}