Webhooks are used to communicate events in the system as status changes or important notifications. The data contained in a Webhook call might sometimes hold sensitive data. To ensure that the Webhook originated from Magnius, all our Webhooks are digitally signed.
Below you find a detailed description of the process to verify if a Webhook call originated from Magnius:
To be able to verify Webhooks signature, you first need to download our public key:
Payground | Payground public key |
Live | Live public key |
The signature can be found on the X-signature
HTTP header, encoded to Base64.
To verify the signature, you need from the Webhook Request: the body
, the X-signature
header and the public key available above.
const fs = require('fs'), path = require('path'), crypto = require('crypto'), verify = crypto.createVerify('SHA1');
let body = 'TheRequestBodyGoesHere'; // the body from the Webhook request
let signature = 'TheRequestXSignatureGoesHere'; // the X-Signature request header
let publicKeyPath = 'path/to/the/downloaded/key/webhookPublicKey.pem'; // the path to the key
let publicKey = fs.readFileSync(publicKeyPath); // read
verify.update(body); // sets the message to be verified
console.log(verify.verify(publicKey, signature, 'base64')); // test it
$body = 'TheRequestBodyGoesHere'; // the body from the Webhook request
$xSignature = 'TheRequestXSignatureGoesHere'; // the X-Signature request header
$publicKeyPath = 'path/to/the/downloaded/key/webhookPublicKey.pem'; // the path to the key
$base64DecodedXSignature = base64_decode($xSignature); // X-Signature is base64 encoded
$publicKey = openssl_pkey_get_public(file_get_contents($publicKeyPath));
echo openssl_verify($body, $base64DecodedXSignature, $publicKey); // test it
import base64
from OpenSSL import crypto
public_key_path = 'path/to/the/downloaded/key/webhookPublicKey.pem' # the path to the key
def verify(message, signature, public_key_path):
try:
key = crypto.load_certificate(crypto.FILETYPE_PEM, open(key_path, 'rb').read())
crypto.verify(key, base64.urlsafe_b64decode(xsignature), message, 'sha1') # when successful, this call returns None
return True
except: # when unsuccessful, python raises an Error
return False
body = 'TheRequestBodyGoesHere' # the body from the Webhook request
xsignature = 'TheRequestXSignatureGoesHere' # the X-Signature from the Webhook request
print(verify(body, xsignature, public_key_path)) # test it
require 'openssl'
require 'base64'
public_key_path = 'path/to/the/downloaded/key/webhookPublicKey.pem' # the path to the key
body = 'TheRequestBodyGoesHere' # the body from the Webhook request
signature = 'TheRequestXSignatureGoesHere' # the X-Signature request header
key = OpenSSL::X509::Certificate.new File.read public_key_path # creates the certificate object from path
print(key.public_key.verify(OpenSSL::Digest::SHA1.new, Base64.decode64(signature), body)) # test it
This example uses the .pem file. It's also possible to first convert the .pem file to XML and simplify this.
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
var Body = @"TheRequestBodyGoesHere"; // the body from the Webhook request
var Signature = "TheRequestXSignatureGoesHere"; // the X-Signature request header
var PublicKeyPath = @"path/to/the/downloaded/key/webhookPublicKey.pem"; // the path to the key
byte[] body = Encoding.UTF8.GetBytes(Body);
byte[] signature = Convert.FromBase64String(Signature); // X-Signature is base64 encoded
RSACryptoServiceProvider RSAVerifier = new RSACryptoServiceProvider();
RSAVerifier.FromXmlString(PemToXML(PublicKeyPath)); // Pem to XML
if (RSAVerifier.VerifyData(body, "SHA1", signature))
{
Console.WriteLine("Signature verified");
}
else
{
Console.WriteLine("ERROR: Signature not valid!");
}
Console.ReadLine();
}
private static string PemToXML(string PublicKeyPath)
{
StreamReader PubKeyReader = File.OpenText(PublicKeyPath);
string pem = PubKeyReader.ReadToEnd();
return GetXmlRsaKey(pem, obj =>
{
var publicKey = (RsaKeyParameters)obj;
return DotNetUtilities.ToRSA(publicKey);
}, rsa => rsa.ToXmlString(false));
}
private static string GetXmlRsaKey(string pem, Func