XML-Security / signxml

Python XML Signature and XAdES library

Home Page:https://xml-security.github.io/signxml/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

doubts in canonizing XML

dbrab opened this issue · comments

commented

Hello, I have a question about the canonicalization method, it happens that I was trying to pass the digital signature method from .net to nodejs using the xml-signed library, but the digest hashes differed, after thinking about it a lot I found that in .net using the XmlSigned library, it canonizes my xml in a different way before getting the digest.

Original document

<?xml version="1.0" encoding="utf-8"?>
  <SemillaModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <valor>pZCD+cgGPsMOXJNjnhMKDrhexYnOk649D9aC3et68UdDx+6EfF92hmeC1lWXjVQQzRcONdIe0ZTTNfAdbxLSXdlGM92ytH27JlM45pKKdq0MrtbudsPX1XfJevC4gNCtrcYNE11WLVIeOB7i1WqdKg==</valor>
    <fecha>2023-01-02T14:22:00.6276364-04:00</fecha>
  </SemillaModel>

in .net the document is canonized to this..

<SemillaModel xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

using the signed-xml library, canonicalize to this(no change)

<SemillaModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
The reference code is the one I use in .net, it's something standard and I couldn't change it since it's the only one that my provider accepts, so I would like to know why this happens, everything else is the same, only the hashes varied, I solved it replacing at the beginning the tags that gave problems .. but I don't think it's the solution.

let xml=fs.readFileSync(`./xml/${fileName}.xml`,'utf-8');
xml = xml.replace(/>\s*/g, '>');  // Replace "> " with ">"
xml = xml.replace(/\s*</g, '<');  // Replace "< " with "<"
const cad='xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"';
const rep='xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"';
xml=xml.replace(cad,rep)
xml=xml.trim();

    var sig = new SignedXml()
    sig.digestAlgorithm ="http://www.w3.org/2001/04/xmlenc#sha256";
    sig.signatureAlgorithm = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
    sig.keyInfoProvider = new keyProvider(public_key)
    sig.canonicalizationAlgorithm = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
    sig.addReference(`//*[local-name(.)='SemillaModel']`, ["http://www.w3.org/2000/09/xmldsig#enveloped-signature"], "http://www.w3.org/2001/04/xmlenc#sha256", "", "", "", true)
    sig.signingKey =signingKey;
    sig.computeSignature(xml)
    fs.writeFileSync(xml_sign, sig.getSignedXml())

Can someone clear me why this happens? if the methods of canonization in theory are the same
Finding this problem took me many hours to be honest, since it was not easy for me to debug the .net library due to the scant information about it and being out of my stack.

Not sure why you're filing this issue here since this project has nothing to do with either the .net or node.js libraries mentioned.

With that said, the .net canonicalization is correct, and the other one is not. Namespace attributes must be ordered lexicographically in canonical XML. Canonical XML Version 1.1, section 2.2, Document Order.