Critical Security Step! Always verify webhook signatures to ensure requests actually came from BlockBee and haven't been tampered with. This prevents malicious actors from sending fake webhooks to your application.
BlockBee uses a 1024-bit RSA SHA256 signature with a public-key signature scheme to sign every webhook sent to your service. This ensures all data was sent from BlockBee and can be trusted.
How BlockBee Signature Works
What Gets Signed
- For GET requests: The full URL including all query parameters is signed
- For POST requests: The entire request body is signed
Signature Details
- Algorithm: RSA SHA256 with PKCS1v15 padding
- Key Size: 1024-bit RSA key
- Header: Signature is sent in the
x-ca-signature
header - Encoding: Signature is base64-encoded
- Public Key: Available at
https://api.blockbee.io/pubkey/
Example Signed Data
For a GET request, the signed data looks like:
https://yoursite.com/webhook?uuid=dbfcb40e-5a6b-4305-9fa2-b0fbda6e3ff2&address_in=3PFoGK63cVVUWnd2vu7W1kM83NXUfvzMqM&txid_in=a2174ffd39289100709f2a07b129cdbba69df2e22e5be1830221dab1fd4e332c&value_coin=0.05&confirmations=3&pending=0
For a POST request, the signed data is the raw request body:
uuid=dbfcb40e-5a6b-4305-9fa2-b0fbda6e3ff2&address_in=3PFoGK63cVVUWnd2vu7W1kM83NXUfvzMqM&txid_in=a2174ffd39289100709f2a07b129cdbba69df2e22e5be1830221dab1fd4e332c&value_coin=0.05&confirmations=3&pending=0
Implementation Examples
// Node.js verification
const crypto = require('crypto');
// BlockBee's public key (you can also fetch from https://api.blockbee.io/pubkey/)
const BLOCKBEE_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3FT0Ym8b3myVxhQW7ESuuu6lo
dGAsUJs4fq+Ey//jm27jQ7HHHDmP1YJO7XE7Jf/0DTEJgcw4EZhJFVwsk6d3+4fy
Bsn0tKeyGMiaE6cVkX0cy6Y85o8zgc/CwZKc0uw6d5siAo++xl2zl+RGMXCELQVE
ox7pp208zTvown577wIDAQAB
-----END PUBLIC KEY-----`;
function verifyBlockBeeSignature(req) {
try {
// Get signature from header
const signature_b64 = req.headers['x-ca-signature'];
if (!signature_b64) {
console.error('Missing x-ca-signature header');
return false;
}
// Decode signature from base64
const signature = Buffer.from(signature_b64, 'base64');
// Determine what data to verify based on request method
let dataToVerify;
if (req.method === 'GET') {
// For GET requests, sign the full URL
dataToVerify = req.protocol + '://' + req.get('host') + req.originalUrl;
} else {
// For POST requests, sign the raw body
dataToVerify = req.rawBody; // You need raw body middleware
}
// Create verifier and verify signature
const verifier = crypto.createVerify('RSA-SHA256');
verifier.update(dataToVerify);
const isValid = verifier.verify(BLOCKBEE_PUBLIC_KEY, signature);
if (!isValid) {
console.error('Invalid signature');
}
return isValid;
} catch (error) {
console.error('Signature verification error:', error);
return false;
}
}
// Express middleware to capture raw body
function captureRawBody(req, res, next) {
req.rawBody = '';
req.on('data', chunk => {
req.rawBody += chunk.toString();
});
req.on('end', () => {
next();
});
}
// Usage in Express
app.use('/webhook', captureRawBody);
app.post('/webhook', (req, res) => {
if (!verifyBlockBeeSignature(req)) {
return res.status(401).send('Invalid signature');
}
// Process webhook safely
console.log('Verified webhook received');
res.status(200).send('*ok*');
});
Test signature verification! Make sure to test the signature verification when testing your integration as it's a very important safety feature.
Security Best Practices
- Always verify signatures - Never skip signature verification in production
- Use HTTPS - Ensure your webhook endpoint uses HTTPS
- Implement rate limiting - Prevent abuse of your webhook endpoint
- Log security events - Log all signature verification failures
- Validate webhook data - Even verified webhooks should have data validation
- Use idempotency - Prevent duplicate processing of webhooks
Signature Verification Complete! Your webhook endpoint is now secure and can trust that all requests come from BlockBee. Remember to test thoroughly and monitor for any verification failures.