artur-rodrigues.com

Verifying X509 Signatures in Python

by

While building SNS-Twilio, I had to verify the signature of the SNS notification received by the application. Amazon SNS uses a X509 certificate to sign its messages, so on my end I had to load AWS’s public certificate, build the message, and verify that the provided signature was indeed valid.

Unless you want to fall back to openssl and the subprocess module, you will need to use the awesome M2Crypto module. I spent some time playing with it and looking at other people’s attempts until I could do it right, so here it is:

from M2Crypto import X509
from base64 import b64decode

cert = X509.load_cert_string(str(r.text))
pubkey = cert.get_pubkey()
pubkey.reset_context(md='sha1')
pubkey.verify_init()
pubkey.verify_update(str_to_sign.encode())
result = pubkey.verify_final(b64decode(signature))
if result != 1:
    raise Exception('Signature could not be verified')
else:
    return True

Please do note that the public certificate is loaded from a string, and that AWS uses the SHA1withRSA hashing algorithm.