Nodejs xml digital signature digest does not match

1.2k Views Asked by At

I am using xml-crypto library to digitally sign the XML. The library is generating the digitally signed XML with no problem. However, when I try to verify it, it throws an error:

invalid signature: for uri #_0 calculated digest is h101O5ejoHaQM8NHtoPDHqPLGnk= but the xml to validate supplies digest mcTUHt6CDkvKevb+7hBObU1uomY=

I am just trying to verify the XML signature in the same code block where it is being generating but it is failing.

    const sig = new SignedXml();
    sig.addReference("//*[local-name(.)='data']");
    sig.keyInfoProvider = keyProvider;
    sig.signingKey = privateKey;
    
    sig.computeSignature(xml);
    const signedXML = sig.getSignedXml();
    logger.debug(`Signed XMl: ${signedXML}`);
    
    const doc = new dom().parseFromString(signedXML);
    logger.debug(select(doc, "//*[local-name(.)='data']")[0].toString());
    const signature = select(doc, "//*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']")[0];
    const signed = new SignedXml();
    signed.keyInfoProvider = keyProvider;
    signed.loadSignature(signature.toString());
    const res = signed.checkSignature(signedXML);
    if (!res) {
        logger.error(JSON.stringify(signed.validationErrors));
    } else {
        logger.debug('Signature is valid');
    }
1

There are 1 best solutions below

0
On

Is 'data' the root node of the XML you are signing?

    sig.addReference("//*[local-name(.)='data']");

If so, that could be the problem. See this article by the package author https://dzone.com/articles/check-out-digital-signature

sig.getSignedXml() returns the original xml document with the signature pushed as the last child of the root node (as above). This assumes you are not signing the root node but only sub node(s) otherwise this is not valid.

If you want to sign the root node, you will need to fetch the signature part separately using getSignatureXml() and insert it into the original xml (with the Id attributes added on):

If you do sign the root node call sig.getSignatureXml() to get just the signature part and sig.getOriginalXmlWithIds() to get the original xml with Id attributes added on relevant elements (required for validation).