Reputation: 103
I would need to sign a SAML assertion as it's possible to do on this page : https://www.samltool.com/sign_response.php
From my side, I'm using Python, and my SAML is in a string.
What would you advise ?
Best regards,
Nico.
Upvotes: 2
Views: 2894
Reputation: 103
I finally made it using signxml lib.
Just to remind, I wanted to sign the SAML assertion.
I get the unsigned SAML from a file. Then I place this tag <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="placeholder"></ds:Signature> between Issuer tag and Subject tag, as it's recommended by signxml lib. And finally, I sign my SAML and verify the signature. Note that I changed the c14n_algorithm to be compatible with my services.
Here's the code :
import re
from lxml import etree
from signxml import XMLSigner, XMLVerifier
with open('saml_to_sign.xml', 'r') as file :
data_to_sign = file.read()
with open("/vagrant/my_cert.crt", "r") as cert,\
open("/vagrant/my_key.key", "r") as key:
certificate = cert.read()
private_key = key.read()
p = re.search('<Subject>', data_to_sign).start()
tmp_message = data_to_sign[:p]
tmp_message = tmp_message +\
'<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="placeholder"></ds:Signature>'
data_to_sign = tmp_message + data_to_sign[p:]
print(data_to_sign)
saml_root = etree.fromstring(data_to_sign)
signed_saml_root = XMLSigner(c14n_algorithm="http://www.w3.org/2001/10/xml-exc-c14n#")\
.sign(saml_root, key=private_key, cert=certificate)
verified_data = XMLVerifier().verify(signed_saml_root, x509_cert=certificate).signed_xml
signed_saml_root_str = etree.tostring(signed_saml_root, encoding='unicode')
print(signed_saml_root_str)
Upvotes: 4