Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Break line in tag signature #196

Open
edsonbernar opened this issue Nov 25, 2021 · 5 comments
Open

Break line in tag signature #196

edsonbernar opened this issue Nov 25, 2021 · 5 comments

Comments

@edsonbernar
Copy link

edsonbernar commented Nov 25, 2021

Hi,
Is it possible to avoid line breaks in the signature tag that is generated?
Some servers refuse these characters.

<NFe xmlns="http://www.portalfiscal.inf.br/nfe"><infNFe versao="4.00"><ide><cUF>35</cUF><cNF>1212</cNF><natOp>VENDA MERC. ADQ. OU REC. DE TERC</natOp><mod>55</mod><serie>1</serie><nNF>1242</nNF></infNFe><Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="#NFe35211107457285000133550010010010351942498581">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>RgXK0snmSsBVA4KbqOnH1jhPZOI=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>ovwmdOLfXapXCvXF39</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>MIIIHjCCBgagAwIBAgI</X509Certificate>
</X509Data>
</KeyInfo>
</Signature></NFe>

Code

element_signed = xml_element.find(".//*[@Id='%s']" % reference)
parent = element_signed.getparent()        
ref_uri = "#NFe35211107457285000133550010010010351942498581"

signature_node = xmlsec.template.create(
            element_signed,
            c14n_method=consts.TransformInclC14N,
            sign_method=consts.TransformRsaSha1,
        )      
parent.append(signature_node)
                      
ref = xmlsec.template.add_reference(signature_node, xmlsec.Transform.SHA1, uri=ref_uri)

xmlsec.template.add_transform(ref, consts.TransformEnveloped)
xmlsec.template.add_transform(ref, consts.TransformInclC14N)               

ki = xmlsec.template.ensure_key_info(signature_node)
xmlsec.template.add_x509_data(ki)

ctx = xmlsec.SignatureContext()
ctx.key = key
ctx.key.load_cert_from_memory(self.certificado, consts.KeyDataFormatPem)        
ctx.register_id(element_signed, id_attr='Id')
                                   
ctx.sign(signature_node)

return etree.tostring(xml_element, encoding=str)
@hoefling
Copy link
Member

@edsonbernar what line breaks do you mean exactly? The string representation of the XML tree is generated by lxml's etree.tostring() function, this isn't part of xmlsec.

@edsonbernar
Copy link
Author

Hi,
The code 'return etree.tostring(xml_element, encoding=str)' is just my output. Signing takes place before that.

If you add the code below before 'ctx.sign(signature_node)' then the signature is generated in the correct pattern.

signature_node = etree.tostring(
signature_node, encoding=str).replace('\n','')
signature_node = etree.fromstring(signature_node)
parent.append(signature_node)
ctx.sign(signature_node)

It seems to me that 'xmlsec.template.create()' introduces line breaks throughout the signature node.
At least that's what I notice when I open the signed xml in an editor.
Using another library to sign (signxml), the signature node does not come out with line breaks.

@hoefling
Copy link
Member

If you mean the line breaks in the base64-encoded signature value, then you can control the maximal line size via xmlsec.base64_default_line_size, e.g.

import xmlsec
xmlsec.base64_default_line_size(size=4096)
...

Otherwise, please provide a reproducible example that illustrates what you mean exactly.

@edsonbernar
Copy link
Author

I already use 'xmlsec.base64_default_line_size' to avoid line breaks in the certificate.
I will try to make the xml signature with the 'Signature' element already existing in the xml, without using 'xmlsec.template.create' to create and then add.

@edsonbernar
Copy link
Author

I tested it and the result was the same. Because of the breaks the 'SignatureValue' is different from other libraries (.Net, Python Signxml)
The 'DigestValue' is calculated the same in all.
Anyway thanks for the help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants