I’m encountering issues with validating the signature of a decoded SAML response in Python using its corresponding public key. Despite implementing the verification process, I consistently receive a “Signature verification failed” error.
Here’s a snippet of the Python code I’ve been working with:
import base64
import xmlsec
from lxml import etree
# Functions for decoding SAML response and parsing XML
def decode_response(encoded_response):
return base64.b64decode(encoded_response)
def parse_xml(xml_string):
return etree.fromstring(xml_string.encode('utf-8'))
# Function to verify SAML signature
def verify_saml_signature(xml_doc, cert_file):
ns = {
'samlp': 'urn:oasis:names:tc:SAML:2.0:protocol',
'saml': 'urn:oasis:names:tc:SAML:2.0:assertion',
'ds': 'http://www.w3.org/2000/09/xmldsig#',
'xenc': 'http://www.w3.org/2001/04/xmlenc#'
}
signature_node = xml_doc.xpath('//ds:Signature', namespaces=ns)[0]
ctx = xmlsec.SignatureContext()
with open(cert_file, 'rb') as f:
key = xmlsec.Key.from_memory(f.read(), xmlsec.KeyFormat.CERT_PEM, None)
ctx.key = key
try:
ctx.verify(signature_node)
return True, "Signature is valid."
except xmlsec.Error as e:
return False, f"Signature verification failed: {str(e)}"
# Sample SAML response and certificate file
cert_file = 'dev_okta.cert'
decoded_saml_response = '''
<Your sample SAML response goes here>
'''
xml_doc = parse_xml(decoded_saml_response)
signature_verified, verification_result = verify_saml_signature(xml_doc, cert_file)
print(verification_result)
Despite my efforts, I keep receiving the following error:
# Signature verification failed: (1, 'failed to verify')
I’d appreciate it if someone could test the provided code and confirm whether it produces a valid result. Additionally, any suggestions for alternative methods to validate the assertion with a public key would be highly valued.
Feel free to adjust the content as needed, and don’t forget to replace with an actual sample SAML response for others to test the code effectively.