HMAC-SHA256 Signature Verification
All webhook payloads between adapters and ZenEdge are signed using HMAC-SHA256 to ensure authenticity and integrity.
Algorithm
- Take the raw JSON payload body
- Compute HMAC-SHA256 using the shared secret
- Hex-encode the digest
- Compare with the signature in the header
Header
X-Webhook-Signature: sha256=a1b2c3d4e5f6...
Implementation Examples
Node.js
const crypto = require('crypto');
function verifySignature(payload, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
Python
import hmac
import hashlib
def verify_signature(payload: bytes, signature: str, secret: str) -> bool:
expected = 'sha256=' + hmac.new(
secret.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)
Go
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
)
func verifySignature(payload []byte, signature, secret string) bool {
mac := hmac.New(sha256.New, []byte(secret))
mac.Write(payload)
expected := "sha256=" + hex.EncodeToString(mac.Sum(nil))
return hmac.Equal([]byte(signature), []byte(expected))
}
Security Best Practices
- Always use
timingSafeEqual(or equivalent) to prevent timing attacks - Verify the signature before parsing the JSON payload
- Store the shared secret securely (environment variable, not in code)
- Rotate secrets periodically
Next Steps
- Tutorial: Build Your First Adapter — Build a working adapter
- Certification Process — Get your adapter certified