Skip to content

Instantly share code, notes, and snippets.

@osvalr
Created February 25, 2017 19:36
Show Gist options
  • Save osvalr/223fe203675df0eb31baa60b19ab95d0 to your computer and use it in GitHub Desktop.
Save osvalr/223fe203675df0eb31baa60b19ab95d0 to your computer and use it in GitHub Desktop.
Sign XML file in python with a x509 certificate
# coding: utf-8
from lxml import etree
from signxml import xmldsig
cert = open('cert.pem').read()
key = open('key.pem').read()
doc = etree.parse('sample.xml').getroot()
root = etree.fromstring(
etree.tostring(doc),
parser=etree.XMLParser(encoding='ISO-8859-1'))
signed_root = xmldsig(root,
digest_algorithm='sha1').sign(algorithm='rsa-sha1',
key=key,
cert=cert)
signed_root.xpath(
'//ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/ds:Signature',
namespaces={
'ext': 'urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2',
'ds': 'http://www.w3.org/2000/09/xmldsig#'
})[0].attrib['Id'] = 'SignSUNAT'
doc = etree.tostring(signed_root, encoding='ISO-8859-1')
with open('result.xml', 'w') as f:
f.write(etree.tostring(signed_root, xml_declaration=True, encoding="ISO-8859-1", pretty_print=True))
@osvalr
Copy link
Author

osvalr commented Feb 25, 2017

sample.xml

<?xml version='1.0' encoding='ISO-8859-1'?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:ccts="urn:un:unece:uncefact:documentation:2" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2" xmlns:sac="urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1" xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <ext:UBLExtensions>
    <ext:UBLExtension>
      <ext:ExtensionContent>
        <ds:Signature Id="placeholder"> </ds:Signature>
      </ext:ExtensionContent>
    </ext:UBLExtension>
  </ext:UBLExtensions>
  <cbc:UBLVersionID>2.0</cbc:UBLVersionID>
  <cbc:CustomizationID>1.0</cbc:CustomizationID>
  <cac:Signature>
    <cbc:ID>IDSignKG</cbc:ID>
    <cac:SignatoryParty>
      <cac:PartyIdentification>
        <cbc:ID>XXXXXXXXXXX</cbc:ID>
      </cac:PartyIdentification>
      <cac:PartyName>
        <cbc:Name>My Great Company</cbc:Name>
      </cac:PartyName>
    </cac:SignatoryParty>
    <cac:DigitalSignatureAttachment>
      <cac:ExternalReference>
        <cbc:URI>#SignatureKG</cbc:URI>
      </cac:ExternalReference>
    </cac:DigitalSignatureAttachment>
  </cac:Signature>
</Invoice>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment