Skip to content

digest is invalid because the computed digest differs from the digest in the XML #472

Closed

Description

@MateoF01

Hello. Im getting a problem when i try to sign an xml document. I readed some issues related but i cant fin de solution yet.
After executing my code, y tried to validate the signature with this tool https://tools.chilkat.io/xmlDsigVerify.cshtml and i get:

Signature is Invalid
Number of Reference Digests = 1
Reference 1 digest is invalid because the computed digest differs from the digest in the XML. 

Right now my code is this:

import forge from 'node-forge'
import { readFileSync } from 'fs'
import { SignedXml } from 'xml-crypto'
import { createClient, WSSecurityCert } from 'soap'
import { EXTRACT_X509_CERTS } from 'xml-crypto/lib/utils.js'

SignedXml.getKeyInfoContent = ({ publicCert, prefix }) => {
  if (publicCert == null) return null
  prefix = prefix ? `${prefix}:` : ''

  let x509Certs = ''

  if (Buffer.isBuffer(publicCert)) {
    publicCert = publicCert.toString('latin1')
  }

  let publicCertMatches = []

  if (typeof publicCert === 'string') {
    publicCertMatches = publicCert.match(EXTRACT_X509_CERTS) || []
  }

  if (publicCertMatches.length > 0) {
    x509Certs = publicCertMatches
      .map(c => {
        const certificate = forge.pki.certificateFromPem(c)
        const issuerName = certificate.issuer.attributes.map(attr => `${attr.shortName}=${attr.value}`).join(', ')
        const serialNumber = certificate.serialNumber
        return (
          `<${prefix}X509IssuerSerial>` +
          `<${prefix}X509IssuerName>${issuerName}</${prefix}X509IssuerName>` +
          `<${prefix}X509SerialNumber>${BigInt(`0x${serialNumber}`).toString()}</${prefix}X509SerialNumber>` +
          `</${prefix}X509IssuerSerial>`
        )
      })
      .join('')
  }

  return `<${prefix}X509Data>${x509Certs}</${prefix}X509Data>`
}



const firmarXml = (xml, certPath, password) => {
  const { privateKey, certificate } = retornaCertificado(certPath, password)

  const sig = new SignedXml({ privateKey: privateKey, publicCert: certificate })
  
  sig.signatureAlgorithm = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'
  sig.canonicalizationAlgorithm = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315'

  sig.addReference({
    xpath: "//*[local-name(.)='eFact']",
    transforms: ["http://www.w3.org/2000/09/xmldsig#enveloped-signature", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"],
    digestAlgorithm: 'http://www.w3.org/2001/04/xmlenc#sha256',
    isEmptyUri: true,
  })

  sig.computeSignature(xml, {
    location: {
      reference: "//*[local-name(.)='CFE']",
      action: 'append',
    },
  })
  
  return { Datain: { xmlData: sig.getSignedXml() } }
}

and the xml im trying to sign is this, with the signature generated there

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DGICFE:EnvioCFE version="1.0" xsi:schemaLocation="http://cfe.dgi.gub.uy EnvioCFE_v1.24.xsd"
	xmlns:DGICFE="http://cfe.dgi.gub.uy"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<DGICFE:Caratula version="1.0">
		<DGICFE:RutReceptor>219999830019</DGICFE:RutReceptor>
		<DGICFE:RUCEmisor>219470980013</DGICFE:RUCEmisor>
		<DGICFE:Idemisor>3169</DGICFE:Idemisor>
		<DGICFE:CantCFE>1</DGICFE:CantCFE>
		<DGICFE:Fecha>2024-05-20T13:10:00-03:00</DGICFE:Fecha>
		<DGICFE:X509Certificate>MIIGwzCCBKugAwIBAgIVAJq2gU...</DGICFE:X509Certificate>
	</DGICFE:Caratula>
	<ns0:CFE version="1.0"
		xmlns:ns0="http://cfe.dgi.gub.uy">
		<ns0:eFact>
			<ns0:TmstFirma>2024-05-22T11:51:55-03:00</ns0:TmstFirma>
			<ns0:Encabezado>
				<ns0:IdDoc>
					<ns0:TipoCFE>111</ns0:TipoCFE>
					<ns0:Serie>A</ns0:Serie>
					<ns0:Nro>1</ns0:Nro>
					<ns0:FchEmis>2024-04-25</ns0:FchEmis>
					<ns0:FmaPago>1</ns0:FmaPago>
				</ns0:IdDoc>
				<ns0:Emisor>
					<ns0:RUCEmisor>219470980013</ns0:RUCEmisor>
					<ns0:RznSoc>DGI PRUEBA SERVICIOS WEB</ns0:RznSoc>
					<ns0:CdgDGISucur>1</ns0:CdgDGISucur>
					<ns0:DomFiscal>FERNANDEZ CRESPO AVDA. DANIEL 1534</ns0:DomFiscal>
					<ns0:Ciudad>MONTEVIDEO</ns0:Ciudad>
					<ns0:Departamento>MONTEVIDEO</ns0:Departamento>
				</ns0:Emisor>
				<ns0:Receptor>
					<ns0:TipoDocRecep>2</ns0:TipoDocRecep>
					<ns0:CodPaisRecep>UY</ns0:CodPaisRecep>
					<ns0:DocRecep>214844360018</ns0:DocRecep>
					<ns0:RznSocRecep>DGI</ns0:RznSocRecep>
					<ns0:DirRecep>Fernandez Crespo 1534</ns0:DirRecep>
					<ns0:CiudadRecep>Montevideo</ns0:CiudadRecep>
				</ns0:Receptor>
				<ns0:Totales>
					<ns0:TpoMoneda>UYU</ns0:TpoMoneda>
					<ns0:MntNetoIVATasaBasica>20000</ns0:MntNetoIVATasaBasica>
					<ns0:IVATasaMin>10</ns0:IVATasaMin>
					<ns0:IVATasaBasica>22</ns0:IVATasaBasica>
					<ns0:MntIVATasaBasica>4400</ns0:MntIVATasaBasica>
					<ns0:MntTotal>24400</ns0:MntTotal>
					<ns0:CantLinDet>3</ns0:CantLinDet>
					<ns0:MontoNF>5000</ns0:MontoNF>
					<ns0:MntPagar>29400</ns0:MntPagar>
				</ns0:Totales>
			</ns0:Encabezado>
			<ns0:Detalle>
				<ns0:Item>
					<ns0:NroLinDet>1</ns0:NroLinDet>
					<ns0:IndFact>3</ns0:IndFact>
					<ns0:NomItem>Harina</ns0:NomItem>
					<ns0:Cantidad>10</ns0:Cantidad>
					<ns0:UniMed>kg</ns0:UniMed>
					<ns0:PrecioUnitario>1000</ns0:PrecioUnitario>
					<ns0:MontoItem>10000</ns0:MontoItem>
				</ns0:Item>
				<ns0:Item>
					<ns0:NroLinDet>2</ns0:NroLinDet>
					<ns0:IndFact>3</ns0:IndFact>
					<ns0:NomItem>Azucar</ns0:NomItem>
					<ns0:Cantidad>5</ns0:Cantidad>
					<ns0:UniMed>kg</ns0:UniMed>
					<ns0:PrecioUnitario>2000</ns0:PrecioUnitario>
					<ns0:MontoItem>10000</ns0:MontoItem>
				</ns0:Item>
				<ns0:Item>
					<ns0:NroLinDet>3</ns0:NroLinDet>
					<ns0:IndFact>6</ns0:IndFact>
					<ns0:NomItem>Bicicleta</ns0:NomItem>
					<ns0:Cantidad>1</ns0:Cantidad>
					<ns0:UniMed>N/A</ns0:UniMed>
					<ns0:PrecioUnitario>5000</ns0:PrecioUnitario>
					<ns0:MontoItem>5000</ns0:MontoItem>
				</ns0:Item>
			</ns0:Detalle>
			<ns0:CAEData>
				<ns0:CAE_ID>90240894778</ns0:CAE_ID>
				<ns0:DNro>1</ns0:DNro>
				<ns0:HNro>100</ns0:HNro>
				<ns0:FecVenc>2026-04-24</ns0:FecVenc>
			</ns0:CAEData>
		</ns0:eFact>
		<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/2001/04/xmldsig-more#rsa-sha256"/>
				<Reference URI="">
					<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/2001/04/xmlenc#sha256"/>
					<DigestValue>Rd5Fog4wR0GkbCFCFG41hfzIViWcwzHiEAV+/zRwQZE=</DigestValue>
				</Reference>
			</SignedInfo>
			<SignatureValue>Y6yZwGr/ZrsfXXSyiQyW8fyOvbZyXKXVihlom61/H8tiafAKJm8RpRqKa1dHt2pv072W5srOTb9xYqIaySLzm45TLoKpl526msbOAcCPK+PJzCQIRJB+PkPAQ7m6QXcSvUd0NsxvwZnklBDo2q7/HVv4JfM+8FKt4cgn4KAnOJxM4A2SfQ3hhFK3Uw24dsWaBNTx8ChmBf308czgjaL2RpYWsfCbuCyVROPr7rIbFYcbSvELAdtHtcjI6NTOGciICiV02t/KqH4qk6IHqnTj3elVSkVcKweI8lRDNurMfrJlZ4iKEJo8DKIlWYm5tNoBSRLkcsZNpcRqo53o6DviOg==</SignatureValue>
			<KeyInfo>
				<X509Data>
					<X509IssuerSerial>
						<X509IssuerName>C=UY, L=Montevideo, O=Abitab S.A., OU=ID digital, CN=Abitab</X509IssuerName>
						<X509SerialNumber>883254578286120403153077429716205748582139371646</X509SerialNumber>
					</X509IssuerSerial>
				</X509Data>
			</KeyInfo>
		</Signature>
	</ns0:CFE>
</DGICFE:EnvioCFE>

If someone knows the reason off this problem please share it, im new in the word of signing files, so every help is welcome.

Activity

  1. srd90 commented on May 28, 2024

    @srd90

    It would have been nice to have info about version of xml-crypto.

    Decided to go with following

    {
      "name": "foo",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "author": "",
      "license": "ISC",
      "dependencies": {
        "node-forge": "^1.3.1",
        "xml-crypto": "^6.0.0"
      }
    }

    Furthermore removed / simplified your example code quite a bit in order be able to run it (you could have done that also :) i.e. to provide immediately runnable version):

    //import forge from 'node-forge'
    const forge=require('node-forge')
    //import { readFileSync } from 'fs'
    // ^ not needed to debugging
    //import { SignedXml } from 'xml-crypto'
    const SignedXml=require('xml-crypto').SignedXml
    //import { createClient, WSSecurityCert } from 'soap'
    // ^ not needed to debugging
    //import { EXTRACT_X509_CERTS } from 'xml-crypto/lib/utils.js'
    const EXTRACT_X509_CERTS=require('xml-crypto/lib/utils.js').EXTRACT_X509_CERTS
    
    // https://raw.githubusercontent.com/node-saml/xml-crypto/21201723d2ca9bc11288f62cf72552b7d659b000/test/static/client_public.pem
    var certificate = `
    -----BEGIN CERTIFICATE-----
    MIIBxDCCAW6gAwIBAgIQxUSXFzWJYYtOZnmmuOMKkjANBgkqhkiG9w0BAQQFADAW
    MRQwEgYDVQQDEwtSb290IEFnZW5jeTAeFw0wMzA3MDgxODQ3NTlaFw0zOTEyMzEy
    MzU5NTlaMB8xHTAbBgNVBAMTFFdTRTJRdWlja1N0YXJ0Q2xpZW50MIGfMA0GCSqG
    SIb3DQEBAQUAA4GNADCBiQKBgQC+L6aB9x928noY4+0QBsXnxkQE4quJl7c3PUPd
    Vu7k9A02hRG481XIfWhrDY5i7OEB7KGW7qFJotLLeMec/UkKUwCgv3VvJrs2nE9x
    O3SSWIdNzADukYh+Cxt+FUU6tUkDeqg7dqwivOXhuOTRyOI3HqbWTbumaLdc8juf
    z2LhaQIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEU
    MBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwDQYJKoZIhvcN
    AQEEBQADQQAfIbnMPVYkNNfX1tG1F+qfLhHwJdfDUZuPyRPucWF5qkh6sSdWVBY5
    sT/txBnVJGziyO8DPYdu2fPMER8ajJfl
    -----END CERTIFICATE-----
    `
    
    // https://raw.githubusercontent.com/node-saml/xml-crypto/21201723d2ca9bc11288f62cf72552b7d659b000/test/static/client.pem
    var privateKey = `
    -----BEGIN PRIVATE KEY-----
    MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAL4vpoH3H3byehjj
    7RAGxefGRATiq4mXtzc9Q91W7uT0DTaFEbjzVch9aGsNjmLs4QHsoZbuoUmi0st4
    x5z9SQpTAKC/dW8muzacT3E7dJJYh03MAO6RiH4LG34VRTq1SQN6qDt2rCK85eG4
    5NHI4jceptZNu6Zot1zyO5/PYuFpAgMBAAECgYAhspeyF3M/xB7WIixy1oBiXMLY
    isESFAumgfhwU2LotkVRD6rgNl1QtMe3kCNWa9pCWQcYkxeI0IzA+JmFu2shVvoR
    oL7eV4VCe1Af33z24E46+cY5grxNhHt/LyCnZKcitvCcrzXExUc5n6KngX0mMKgk
    W7skZDwsnKzhyUV8wQJBAN2bQMeASQVOqdfqBdFgC/NPnKY2cuDi6h659QN1l+kg
    X3ywdZ7KKftJo1G9l45SN9YpkyEd9zEO6PMFaufJvZUCQQDbtAWxk0i8BT3UTNWC
    T/9bUQROPcGZagwwnRFByX7gpmfkf1ImIvbWVXSpX68/IjbjSkTw1nj/Yj1NwFZ0
    nxeFAkEAzPhRpXVBlPgaXkvlz7AfvY+wW4hXHyyi0YK8XdPBi25XA5SPZiylQfjt
    Z6iN6qSfYqYXoPT/c0/QJR+orvVJNQJBANhRPNXljVTK2GDCseoXd/ZiI5ohxg+W
    UaA/1fDvQsRQM7TQA4NXI7BO/YmSk4rW1jIeOxjiIspY4MFAIh+7UL0CQFL6zTg6
    wfeMlEZzvgqwCGoLuvTnqtvyg45z7pfcrg2cHdgCXIy9kErcjwGiu6BOevEA1qTW
    Rk+bv0tknWvcz/s=
    -----END PRIVATE KEY-----
    `
    
    // reduced version (no need to have that much data to debug this)
    const inputXml = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <DGICFE:EnvioCFE version="1.0" xsi:schemaLocation="http://cfe.dgi.gub.uy EnvioCFE_v1.24.xsd"
    	xmlns:DGICFE="http://cfe.dgi.gub.uy"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    	<DGICFE:Caratula version="1.0">
    		<DGICFE:RutReceptor>219999830019</DGICFE:RutReceptor>
    	</DGICFE:Caratula>
    	<ns0:CFE version="1.0"
    		xmlns:ns0="http://cfe.dgi.gub.uy">
    		<ns0:eFact>
    			<ns0:TmstFirma>2024-05-22T11:51:55-03:00</ns0:TmstFirma>
    		</ns0:eFact>
    	</ns0:CFE>
    </DGICFE:EnvioCFE>
    `
    
    SignedXml.getKeyInfoContent = ({ publicCert, prefix }) => {
      if (publicCert == null) return null
      prefix = prefix ? `${prefix}:` : ''
    
      let x509Certs = ''
    
      if (Buffer.isBuffer(publicCert)) {
        publicCert = publicCert.toString('latin1')
      }
    
      let publicCertMatches = []
    
      if (typeof publicCert === 'string') {
        publicCertMatches = publicCert.match(EXTRACT_X509_CERTS) || []
      }
    
      if (publicCertMatches.length > 0) {
        x509Certs = publicCertMatches
          .map(c => {
            const certificate = forge.pki.certificateFromPem(c)
            const issuerName = certificate.issuer.attributes.map(attr => `${attr.shortName}=${attr.value}`).join(', ')
            const serialNumber = certificate.serialNumber
            return (
              `<${prefix}X509IssuerSerial>` +
              `<${prefix}X509IssuerName>${issuerName}</${prefix}X509IssuerName>` +
              `<${prefix}X509SerialNumber>${BigInt(`0x${serialNumber}`).toString()}</${prefix}X509SerialNumber>` +
              `</${prefix}X509IssuerSerial>`
            )
          })
          .join('')
      }
    
      return `<${prefix}X509Data>${x509Certs}</${prefix}X509Data>`
    }
    
    const firmarXml = (xml) => {
      // const { privateKey, certificate } = retornaCertificado(certPath, password)
    
      const sig = new SignedXml({ privateKey: privateKey, publicCert: certificate })
      
      sig.signatureAlgorithm = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'
      sig.canonicalizationAlgorithm = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315'
    
      sig.addReference({
        xpath: "//*[local-name(.)='eFact']",
        transforms: ["http://www.w3.org/2000/09/xmldsig#enveloped-signature", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"],
        digestAlgorithm: 'http://www.w3.org/2001/04/xmlenc#sha256',
        isEmptyUri: true,
      })
    
      sig.computeSignature(xml, {
        location: {
          reference: "//*[local-name(.)='CFE']",
          action: 'append',
        },
      })
      
      return { Datain: { xmlData: sig.getSignedXml() } }
    }
    
    console.log(firmarXml(inputXml).Datain.xmlData)

    and when following result is pasted to chilkat it infact says that digests do not match:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <DGICFE:EnvioCFE version="1.0" xsi:schemaLocation="http://cfe.dgi.gub.uy EnvioCFE_v1.24.xsd" xmlns:DGICFE="http://cfe.dgi.gub.uy" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    	<DGICFE:Caratula version="1.0">
    		<DGICFE:RutReceptor>219999830019</DGICFE:RutReceptor>
    	</DGICFE:Caratula>
    	<ns0:CFE version="1.0" xmlns:ns0="http://cfe.dgi.gub.uy">
    		<ns0:eFact>
    			<ns0:TmstFirma>2024-05-22T11:51:55-03:00</ns0:TmstFirma>
    		</ns0:eFact>
    	<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/2001/04/xmldsig-more#rsa-sha256"/><Reference URI=""><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/2001/04/xmlenc#sha256"/><DigestValue>gNFx5CofL1bIBBsVCoo+dX11Nw7o2FzLZ8wZXV8EAac=</DigestValue></Reference></SignedInfo><SignatureValue>lpSZ7wi0NVJJWR19QtvFyOXx7b4Xq7dJgvka+DMqi6C9wrhhdagbpOOENPzD/nB3x4gjtUgZOjrZqEfoQ6aqRAqP9esnYN4Zdy0f0f2jQkwa2s2L4sOatbkpZYAEPXgPQJIjBA6+Qp1SWYRIN1j9UZy3DwFKCwzMC8z56QBQUl8=</SignatureValue><KeyInfo><X509Data><X509IssuerSerial><X509IssuerName>CN=Root Agency</X509IssuerName><X509SerialNumber>262214055838675473468217939292187724434</X509SerialNumber></X509IssuerSerial></X509Data></KeyInfo></Signature></ns0:CFE>
    </DGICFE:EnvioCFE>

    pretty formatted version being:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <DGICFE:EnvioCFE xmlns:DGICFE="http://cfe.dgi.gub.uy" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://cfe.dgi.gub.uy EnvioCFE_v1.24.xsd">
      <DGICFE:Caratula version="1.0">
        <DGICFE:RutReceptor>219999830019</DGICFE:RutReceptor>
      </DGICFE:Caratula>
      <ns0:CFE xmlns:ns0="http://cfe.dgi.gub.uy" version="1.0">
        <ns0:eFact>
          <ns0:TmstFirma>2024-05-22T11:51:55-03:00</ns0:TmstFirma>
        </ns0:eFact>
        <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/2001/04/xmldsig-more#rsa-sha256"/>
            <Reference URI="">
              <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/2001/04/xmlenc#sha256"/>
              <DigestValue>gNFx5CofL1bIBBsVCoo+dX11Nw7o2FzLZ8wZXV8EAac=</DigestValue>
            </Reference>
          </SignedInfo>
          <SignatureValue>lpSZ7wi0NVJJWR19QtvFyOXx7b4Xq7dJgvka+DMqi6C9wrhhdagbpOOENPzD/nB3x4gjtUgZOjrZqEfoQ6aqRAqP9esnYN4Zdy0f0f2jQkwa2s2L4sOatbkpZYAEPXgPQJIjBA6+Qp1SWYRIN1j9UZy3DwFKCwzMC8z56QBQUl8=</SignatureValue>
          <KeyInfo>
            <X509Data>
              <X509IssuerSerial>
                <X509IssuerName>CN=Root Agency</X509IssuerName>
                <X509SerialNumber>262214055838675473468217939292187724434</X509SerialNumber>
              </X509IssuerSerial>
            </X509Data>
          </KeyInfo>
        </Signature>
      </ns0:CFE>
    </DGICFE:EnvioCFE>

    What caught my eye is that you select document fragment to be signed but you set Reference UR="". I have thought that this would mean that when such reference is validated it must take whole document (starting from the root).

    I must emphasize that I am NOT xml signature expert.

    But lets test this assumption and modify

        xpath: "//*[local-name(.)='eFact']",
        // to -->    
        xpath: "//*[local-name(.)='EnvioCFE']",

    i.e. test code is

    //import forge from 'node-forge'
    const forge=require('node-forge')
    //import { readFileSync } from 'fs'
    // ^ not needed to debugging
    //import { SignedXml } from 'xml-crypto'
    const SignedXml=require('xml-crypto').SignedXml
    //import { createClient, WSSecurityCert } from 'soap'
    // ^ not needed to debugging
    //import { EXTRACT_X509_CERTS } from 'xml-crypto/lib/utils.js'
    const EXTRACT_X509_CERTS=require('xml-crypto/lib/utils.js').EXTRACT_X509_CERTS
    
    // https://raw.githubusercontent.com/node-saml/xml-crypto/21201723d2ca9bc11288f62cf72552b7d659b000/test/static/client_public.pem
    var certificate = `
    -----BEGIN CERTIFICATE-----
    MIIBxDCCAW6gAwIBAgIQxUSXFzWJYYtOZnmmuOMKkjANBgkqhkiG9w0BAQQFADAW
    MRQwEgYDVQQDEwtSb290IEFnZW5jeTAeFw0wMzA3MDgxODQ3NTlaFw0zOTEyMzEy
    MzU5NTlaMB8xHTAbBgNVBAMTFFdTRTJRdWlja1N0YXJ0Q2xpZW50MIGfMA0GCSqG
    SIb3DQEBAQUAA4GNADCBiQKBgQC+L6aB9x928noY4+0QBsXnxkQE4quJl7c3PUPd
    Vu7k9A02hRG481XIfWhrDY5i7OEB7KGW7qFJotLLeMec/UkKUwCgv3VvJrs2nE9x
    O3SSWIdNzADukYh+Cxt+FUU6tUkDeqg7dqwivOXhuOTRyOI3HqbWTbumaLdc8juf
    z2LhaQIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEU
    MBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwDQYJKoZIhvcN
    AQEEBQADQQAfIbnMPVYkNNfX1tG1F+qfLhHwJdfDUZuPyRPucWF5qkh6sSdWVBY5
    sT/txBnVJGziyO8DPYdu2fPMER8ajJfl
    -----END CERTIFICATE-----
    `
    
    // https://raw.githubusercontent.com/node-saml/xml-crypto/21201723d2ca9bc11288f62cf72552b7d659b000/test/static/client.pem
    var privateKey = `
    -----BEGIN PRIVATE KEY-----
    MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAL4vpoH3H3byehjj
    7RAGxefGRATiq4mXtzc9Q91W7uT0DTaFEbjzVch9aGsNjmLs4QHsoZbuoUmi0st4
    x5z9SQpTAKC/dW8muzacT3E7dJJYh03MAO6RiH4LG34VRTq1SQN6qDt2rCK85eG4
    5NHI4jceptZNu6Zot1zyO5/PYuFpAgMBAAECgYAhspeyF3M/xB7WIixy1oBiXMLY
    isESFAumgfhwU2LotkVRD6rgNl1QtMe3kCNWa9pCWQcYkxeI0IzA+JmFu2shVvoR
    oL7eV4VCe1Af33z24E46+cY5grxNhHt/LyCnZKcitvCcrzXExUc5n6KngX0mMKgk
    W7skZDwsnKzhyUV8wQJBAN2bQMeASQVOqdfqBdFgC/NPnKY2cuDi6h659QN1l+kg
    X3ywdZ7KKftJo1G9l45SN9YpkyEd9zEO6PMFaufJvZUCQQDbtAWxk0i8BT3UTNWC
    T/9bUQROPcGZagwwnRFByX7gpmfkf1ImIvbWVXSpX68/IjbjSkTw1nj/Yj1NwFZ0
    nxeFAkEAzPhRpXVBlPgaXkvlz7AfvY+wW4hXHyyi0YK8XdPBi25XA5SPZiylQfjt
    Z6iN6qSfYqYXoPT/c0/QJR+orvVJNQJBANhRPNXljVTK2GDCseoXd/ZiI5ohxg+W
    UaA/1fDvQsRQM7TQA4NXI7BO/YmSk4rW1jIeOxjiIspY4MFAIh+7UL0CQFL6zTg6
    wfeMlEZzvgqwCGoLuvTnqtvyg45z7pfcrg2cHdgCXIy9kErcjwGiu6BOevEA1qTW
    Rk+bv0tknWvcz/s=
    -----END PRIVATE KEY-----
    `
    
    // reduced version (no need to have that much data to debug this)
    const inputXml = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <DGICFE:EnvioCFE version="1.0" xsi:schemaLocation="http://cfe.dgi.gub.uy EnvioCFE_v1.24.xsd"
    	xmlns:DGICFE="http://cfe.dgi.gub.uy"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    	<DGICFE:Caratula version="1.0">
    		<DGICFE:RutReceptor>219999830019</DGICFE:RutReceptor>
    	</DGICFE:Caratula>
    	<ns0:CFE version="1.0"
    		xmlns:ns0="http://cfe.dgi.gub.uy">
    		<ns0:eFact>
    			<ns0:TmstFirma>2024-05-22T11:51:55-03:00</ns0:TmstFirma>
    		</ns0:eFact>
    	</ns0:CFE>
    </DGICFE:EnvioCFE>
    `
    
    SignedXml.getKeyInfoContent = ({ publicCert, prefix }) => {
      if (publicCert == null) return null
      prefix = prefix ? `${prefix}:` : ''
    
      let x509Certs = ''
    
      if (Buffer.isBuffer(publicCert)) {
        publicCert = publicCert.toString('latin1')
      }
    
      let publicCertMatches = []
    
      if (typeof publicCert === 'string') {
        publicCertMatches = publicCert.match(EXTRACT_X509_CERTS) || []
      }
    
      if (publicCertMatches.length > 0) {
        x509Certs = publicCertMatches
          .map(c => {
            const certificate = forge.pki.certificateFromPem(c)
            const issuerName = certificate.issuer.attributes.map(attr => `${attr.shortName}=${attr.value}`).join(', ')
            const serialNumber = certificate.serialNumber
            return (
              `<${prefix}X509IssuerSerial>` +
              `<${prefix}X509IssuerName>${issuerName}</${prefix}X509IssuerName>` +
              `<${prefix}X509SerialNumber>${BigInt(`0x${serialNumber}`).toString()}</${prefix}X509SerialNumber>` +
              `</${prefix}X509IssuerSerial>`
            )
          })
          .join('')
      }
    
      return `<${prefix}X509Data>${x509Certs}</${prefix}X509Data>`
    }
    
    const firmarXml = (xml) => {
      // const { privateKey, certificate } = retornaCertificado(certPath, password)
    
      const sig = new SignedXml({ privateKey: privateKey, publicCert: certificate })
      
      sig.signatureAlgorithm = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'
      sig.canonicalizationAlgorithm = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315'
    
      sig.addReference({
        xpath: "//*[local-name(.)='EnvioCFE']",
        transforms: ["http://www.w3.org/2000/09/xmldsig#enveloped-signature", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"],
        digestAlgorithm: 'http://www.w3.org/2001/04/xmlenc#sha256',
        isEmptyUri: true,
      })
    
      sig.computeSignature(xml, {
        location: {
          reference: "//*[local-name(.)='CFE']",
          action: 'append',
        },
      })
      
      return { Datain: { xmlData: sig.getSignedXml() } }
    }
    
    console.log(firmarXml(inputXml).Datain.xmlData)

    output is (and when pasted to chilkat it says that reference 1 digest is valid):

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <DGICFE:EnvioCFE version="1.0" xsi:schemaLocation="http://cfe.dgi.gub.uy EnvioCFE_v1.24.xsd" xmlns:DGICFE="http://cfe.dgi.gub.uy" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    	<DGICFE:Caratula version="1.0">
    		<DGICFE:RutReceptor>219999830019</DGICFE:RutReceptor>
    	</DGICFE:Caratula>
    	<ns0:CFE version="1.0" xmlns:ns0="http://cfe.dgi.gub.uy">
    		<ns0:eFact>
    			<ns0:TmstFirma>2024-05-22T11:51:55-03:00</ns0:TmstFirma>
    		</ns0:eFact>
    	<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/2001/04/xmldsig-more#rsa-sha256"/><Reference URI=""><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/2001/04/xmlenc#sha256"/><DigestValue>sZ3A0cgXIJEMyI5hdGk4aRR8BzVrJgjBPyxBBuhwTXU=</DigestValue></Reference></SignedInfo><SignatureValue>ZFEOBc0jQpBdARFvSp5USZvxhgtL8T+XJpFprrsOIHHDf6SUKlhefqtpbbRMZ2ZRHvLlzomPGhO5BJIiomtB3UuRoEYbduU1wtxoQys8JK6qapan6P6bIUfv4sj1hWHAHWoE5XP9/0LEny8PFVLlbVh4LLcam/wwPWIQQblsmt4=</SignatureValue><KeyInfo><X509Data><X509IssuerSerial><X509IssuerName>CN=Root Agency</X509IssuerName><X509SerialNumber>262214055838675473468217939292187724434</X509SerialNumber></X509IssuerSerial></X509Data></KeyInfo></Signature></ns0:CFE>
    </DGICFE:EnvioCFE>

    pretty printed version:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <DGICFE:EnvioCFE xmlns:DGICFE="http://cfe.dgi.gub.uy" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://cfe.dgi.gub.uy EnvioCFE_v1.24.xsd">
      <DGICFE:Caratula version="1.0">
        <DGICFE:RutReceptor>219999830019</DGICFE:RutReceptor>
      </DGICFE:Caratula>
      <ns0:CFE xmlns:ns0="http://cfe.dgi.gub.uy" version="1.0">
        <ns0:eFact>
          <ns0:TmstFirma>2024-05-22T11:51:55-03:00</ns0:TmstFirma>
        </ns0:eFact>
        <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/2001/04/xmldsig-more#rsa-sha256"/>
            <Reference URI="">
              <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/2001/04/xmlenc#sha256"/>
              <DigestValue>sZ3A0cgXIJEMyI5hdGk4aRR8BzVrJgjBPyxBBuhwTXU=</DigestValue>
            </Reference>
          </SignedInfo>
          <SignatureValue>ZFEOBc0jQpBdARFvSp5USZvxhgtL8T+XJpFprrsOIHHDf6SUKlhefqtpbbRMZ2ZRHvLlzomPGhO5BJIiomtB3UuRoEYbduU1wtxoQys8JK6qapan6P6bIUfv4sj1hWHAHWoE5XP9/0LEny8PFVLlbVh4LLcam/wwPWIQQblsmt4=</SignatureValue>
          <KeyInfo>
            <X509Data>
              <X509IssuerSerial>
                <X509IssuerName>CN=Root Agency</X509IssuerName>
                <X509SerialNumber>262214055838675473468217939292187724434</X509SerialNumber>
              </X509IssuerSerial>
            </X509Data>
          </KeyInfo>
        </Signature>
      </ns0:CFE>
    </DGICFE:EnvioCFE>

    Based on my assumtions (and I must emphasize again that I am NOT xml signature expert) if you sign some fragment / subtree of XML document you must add URI reference to that subtree.

    I.e. lets change this (from original reduced example code):

        isEmptyUri: true,
        // to -->
        isEmptyUri: false,

    i.e. your reduced example code would look something like this:

    //import forge from 'node-forge'
    const forge=require('node-forge')
    //import { readFileSync } from 'fs'
    // ^ not needed to debugging
    //import { SignedXml } from 'xml-crypto'
    const SignedXml=require('xml-crypto').SignedXml
    //import { createClient, WSSecurityCert } from 'soap'
    // ^ not needed to debugging
    //import { EXTRACT_X509_CERTS } from 'xml-crypto/lib/utils.js'
    const EXTRACT_X509_CERTS=require('xml-crypto/lib/utils.js').EXTRACT_X509_CERTS
    
    // https://raw.githubusercontent.com/node-saml/xml-crypto/21201723d2ca9bc11288f62cf72552b7d659b000/test/static/client_public.pem
    var certificate = `
    -----BEGIN CERTIFICATE-----
    MIIBxDCCAW6gAwIBAgIQxUSXFzWJYYtOZnmmuOMKkjANBgkqhkiG9w0BAQQFADAW
    MRQwEgYDVQQDEwtSb290IEFnZW5jeTAeFw0wMzA3MDgxODQ3NTlaFw0zOTEyMzEy
    MzU5NTlaMB8xHTAbBgNVBAMTFFdTRTJRdWlja1N0YXJ0Q2xpZW50MIGfMA0GCSqG
    SIb3DQEBAQUAA4GNADCBiQKBgQC+L6aB9x928noY4+0QBsXnxkQE4quJl7c3PUPd
    Vu7k9A02hRG481XIfWhrDY5i7OEB7KGW7qFJotLLeMec/UkKUwCgv3VvJrs2nE9x
    O3SSWIdNzADukYh+Cxt+FUU6tUkDeqg7dqwivOXhuOTRyOI3HqbWTbumaLdc8juf
    z2LhaQIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEU
    MBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwDQYJKoZIhvcN
    AQEEBQADQQAfIbnMPVYkNNfX1tG1F+qfLhHwJdfDUZuPyRPucWF5qkh6sSdWVBY5
    sT/txBnVJGziyO8DPYdu2fPMER8ajJfl
    -----END CERTIFICATE-----
    `
    
    // https://raw.githubusercontent.com/node-saml/xml-crypto/21201723d2ca9bc11288f62cf72552b7d659b000/test/static/client.pem
    var privateKey = `
    -----BEGIN PRIVATE KEY-----
    MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAL4vpoH3H3byehjj
    7RAGxefGRATiq4mXtzc9Q91W7uT0DTaFEbjzVch9aGsNjmLs4QHsoZbuoUmi0st4
    x5z9SQpTAKC/dW8muzacT3E7dJJYh03MAO6RiH4LG34VRTq1SQN6qDt2rCK85eG4
    5NHI4jceptZNu6Zot1zyO5/PYuFpAgMBAAECgYAhspeyF3M/xB7WIixy1oBiXMLY
    isESFAumgfhwU2LotkVRD6rgNl1QtMe3kCNWa9pCWQcYkxeI0IzA+JmFu2shVvoR
    oL7eV4VCe1Af33z24E46+cY5grxNhHt/LyCnZKcitvCcrzXExUc5n6KngX0mMKgk
    W7skZDwsnKzhyUV8wQJBAN2bQMeASQVOqdfqBdFgC/NPnKY2cuDi6h659QN1l+kg
    X3ywdZ7KKftJo1G9l45SN9YpkyEd9zEO6PMFaufJvZUCQQDbtAWxk0i8BT3UTNWC
    T/9bUQROPcGZagwwnRFByX7gpmfkf1ImIvbWVXSpX68/IjbjSkTw1nj/Yj1NwFZ0
    nxeFAkEAzPhRpXVBlPgaXkvlz7AfvY+wW4hXHyyi0YK8XdPBi25XA5SPZiylQfjt
    Z6iN6qSfYqYXoPT/c0/QJR+orvVJNQJBANhRPNXljVTK2GDCseoXd/ZiI5ohxg+W
    UaA/1fDvQsRQM7TQA4NXI7BO/YmSk4rW1jIeOxjiIspY4MFAIh+7UL0CQFL6zTg6
    wfeMlEZzvgqwCGoLuvTnqtvyg45z7pfcrg2cHdgCXIy9kErcjwGiu6BOevEA1qTW
    Rk+bv0tknWvcz/s=
    -----END PRIVATE KEY-----
    `
    
    // reduced version (no need to have that much data to debug this)
    const inputXml = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <DGICFE:EnvioCFE version="1.0" xsi:schemaLocation="http://cfe.dgi.gub.uy EnvioCFE_v1.24.xsd"
    	xmlns:DGICFE="http://cfe.dgi.gub.uy"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    	<DGICFE:Caratula version="1.0">
    		<DGICFE:RutReceptor>219999830019</DGICFE:RutReceptor>
    	</DGICFE:Caratula>
    	<ns0:CFE version="1.0"
    		xmlns:ns0="http://cfe.dgi.gub.uy">
    		<ns0:eFact>
    			<ns0:TmstFirma>2024-05-22T11:51:55-03:00</ns0:TmstFirma>
    		</ns0:eFact>
    	</ns0:CFE>
    </DGICFE:EnvioCFE>
    `
    
    SignedXml.getKeyInfoContent = ({ publicCert, prefix }) => {
      if (publicCert == null) return null
      prefix = prefix ? `${prefix}:` : ''
    
      let x509Certs = ''
    
      if (Buffer.isBuffer(publicCert)) {
        publicCert = publicCert.toString('latin1')
      }
    
      let publicCertMatches = []
    
      if (typeof publicCert === 'string') {
        publicCertMatches = publicCert.match(EXTRACT_X509_CERTS) || []
      }
    
      if (publicCertMatches.length > 0) {
        x509Certs = publicCertMatches
          .map(c => {
            const certificate = forge.pki.certificateFromPem(c)
            const issuerName = certificate.issuer.attributes.map(attr => `${attr.shortName}=${attr.value}`).join(', ')
            const serialNumber = certificate.serialNumber
            return (
              `<${prefix}X509IssuerSerial>` +
              `<${prefix}X509IssuerName>${issuerName}</${prefix}X509IssuerName>` +
              `<${prefix}X509SerialNumber>${BigInt(`0x${serialNumber}`).toString()}</${prefix}X509SerialNumber>` +
              `</${prefix}X509IssuerSerial>`
            )
          })
          .join('')
      }
    
      return `<${prefix}X509Data>${x509Certs}</${prefix}X509Data>`
    }
    
    const firmarXml = (xml) => {
      // const { privateKey, certificate } = retornaCertificado(certPath, password)
    
      const sig = new SignedXml({ privateKey: privateKey, publicCert: certificate })
      
      sig.signatureAlgorithm = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'
      sig.canonicalizationAlgorithm = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315'
    
      sig.addReference({
        xpath: "//*[local-name(.)='eFact']",
        transforms: ["http://www.w3.org/2000/09/xmldsig#enveloped-signature", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"],
        digestAlgorithm: 'http://www.w3.org/2001/04/xmlenc#sha256',
        isEmptyUri: false,
      })
    
      sig.computeSignature(xml, {
        location: {
          reference: "//*[local-name(.)='CFE']",
          action: 'append',
        },
      })
      
      return { Datain: { xmlData: sig.getSignedXml() } }
    }
    
    console.log(firmarXml(inputXml).Datain.xmlData)

    and resulting xml is (and when pasted to chilkat it reports that digests match)
    Notice how xml-crypto added implicitily Id="_0" to eFact:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <DGICFE:EnvioCFE version="1.0" xsi:schemaLocation="http://cfe.dgi.gub.uy EnvioCFE_v1.24.xsd" xmlns:DGICFE="http://cfe.dgi.gub.uy" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    	<DGICFE:Caratula version="1.0">
    		<DGICFE:RutReceptor>219999830019</DGICFE:RutReceptor>
    	</DGICFE:Caratula>
    	<ns0:CFE version="1.0" xmlns:ns0="http://cfe.dgi.gub.uy">
    		<ns0:eFact Id="_0">
    			<ns0:TmstFirma>2024-05-22T11:51:55-03:00</ns0:TmstFirma>
    		</ns0:eFact>
    	<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/2001/04/xmldsig-more#rsa-sha256"/><Reference URI="#_0"><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/2001/04/xmlenc#sha256"/><DigestValue>F/TXqkksBOGoTcRU6pKJ5cCRPZtYGblpEeDz4aI+S6Y=</DigestValue></Reference></SignedInfo><SignatureValue>cMKIFLrUlgWxBKTe/TOPHpszA4B66l0noE8ED/sSCr7FimrmDs3U0Cx8bTI9C4Zc4bF+215N4pwVcdwqsq3/4LUUl9npmRNSfuQsbhUjdUMXclKALXXY/ORErWQVXDYRWmWAFhWmxiWYCVhP4Wx775ZnbCMqg86sm7VFjWBuP9Y=</SignatureValue><KeyInfo><X509Data><X509IssuerSerial><X509IssuerName>CN=Root Agency</X509IssuerName><X509SerialNumber>262214055838675473468217939292187724434</X509SerialNumber></X509IssuerSerial></X509Data></KeyInfo></Signature></ns0:CFE>
    </DGICFE:EnvioCFE>

    and pretty printed:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <DGICFE:EnvioCFE xmlns:DGICFE="http://cfe.dgi.gub.uy" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" xsi:schemaLocation="http://cfe.dgi.gub.uy EnvioCFE_v1.24.xsd">
      <DGICFE:Caratula version="1.0">
        <DGICFE:RutReceptor>219999830019</DGICFE:RutReceptor>
      </DGICFE:Caratula>
      <ns0:CFE xmlns:ns0="http://cfe.dgi.gub.uy" version="1.0">
        <ns0:eFact Id="_0">
          <ns0:TmstFirma>2024-05-22T11:51:55-03:00</ns0:TmstFirma>
        </ns0:eFact>
        <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/2001/04/xmldsig-more#rsa-sha256"/>
            <Reference URI="#_0">
              <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/2001/04/xmlenc#sha256"/>
              <DigestValue>F/TXqkksBOGoTcRU6pKJ5cCRPZtYGblpEeDz4aI+S6Y=</DigestValue>
            </Reference>
          </SignedInfo>
          <SignatureValue>cMKIFLrUlgWxBKTe/TOPHpszA4B66l0noE8ED/sSCr7FimrmDs3U0Cx8bTI9C4Zc4bF+215N4pwVcdwqsq3/4LUUl9npmRNSfuQsbhUjdUMXclKALXXY/ORErWQVXDYRWmWAFhWmxiWYCVhP4Wx775ZnbCMqg86sm7VFjWBuP9Y=</SignatureValue>
          <KeyInfo>
            <X509Data>
              <X509IssuerSerial>
                <X509IssuerName>CN=Root Agency</X509IssuerName>
                <X509SerialNumber>262214055838675473468217939292187724434</X509SerialNumber>
              </X509IssuerSerial>
            </X509Data>
          </KeyInfo>
        </Signature>
      </ns0:CFE>
    </DGICFE:EnvioCFE>

    Here is link to https://www.w3.org/TR/2008/REC-xmldsig-core-20080610/ for you in order to be able to make your own interpretation of spec.

    Happy debugging / spec interpretation and/or maybe someone with more knowledge about xml signature can jump in and continue from this point on.

  2. MateoF01 commented on May 29, 2024

    @MateoF01
    Author

    Thank you so much for de response. Indeed im using "node-forge": "^1.3.1" and “xml-crypto": "^6.0.0”. 
Yesterday i was trying to replicate your recommendations and i didn't get the digest value error anymore, but the signature still is invalid for some reason that i cant find
. I used your generated certificate and private key too, but the result was the same when i use chillket to test.


    Does anyone know why this could be happening?

  3. MateoF01 commented on May 29, 2024

    @MateoF01
    Author

    Adding more context to the problem: In each EnvioCFE we should put a lot of CFEs, each one with his individual signature for his subtree. Like in this example:

    <?xml version="1.0" encoding="iso-8859-1"?>
    <DGICFE:EnvioCFE version="1.0" xsi:schemaLocation="http://cfe.dgi.gub.uy EnvioCFE_v1.24.xsd"
    	xmlns:DGICFE="http://cfe.dgi.gub.uy"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    	<DGICFE:Caratula version="1.0"> Bla bla bla </DGICFE:Caratula>
    	
    	<ns0:CFE version="1.0" xmlns:ns0="http://cfe.dgi.gub.uy">
    		<ns0:eTck>
    			<ns0:TmstFirma>2016-07-19T15:56:20-03:00</ns0:TmstFirma>
    		</ns0:eTck>
    		<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="">
    					<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>xpXiLtg0nWejadP44Gm7ArFMk7Y=</DigestValue>
    				</Reference>
    			</SignedInfo>
    <SignatureValue>ke8XBfPeT4OzEK5enxCJ6nK367fS9RFx007Yy+A8NAz1+cPIfSgqJhg68nesUCy/XlxbYkFAEU62GvhDg/XdiBFzkwMXac896pVFZr4S45v4FZX3YkosGIi64honz/2tvyUiN977Ek0HtLMoz6DVK5L/5FspvanZqJLEDqEGqJk=</SignatureValue>
    			<KeyInfo>
    				<X509Data>
    					<X509IssuerSerial>
    						<X509IssuerName>CN=Correo Uruguayo - CA, OU=SERVICIOS ELECTRONICOS, O=ADMINISTRACION NACIONAL DE CORREOS, C=UY</X509IssuerName>
    						<X509SerialNumber>155761856642617054135126896023459966393</X509SerialNumber>
    					</X509IssuerSerial>
    				</X509Data>
    			</KeyInfo>
    		</Signature>
    	</ns0:CFE>
    	
    	<ns0:CFE version="1.0" xmlns:ns0="http://cfe.dgi.gub.uy">
    		<ns0:eTck>
    			<ns0:TmstFirma>2016-07-19T15:56:20-03:00</ns0:TmstFirma>
    		</ns0:eTck>
    		<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="">
    					<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>wwNHpZT9gDKlCUalcLcwo5DIkNk=</DigestValue>
    				</Reference>
    			</SignedInfo>
    			<SignatureValue>Oa6tS9NreWBwRR8RhT2rTOr4Gm3OSWklWzKR3Z+u+LGzQo1C+EskajdxmzdkKvVMgQ4O9CmNL+6RILCFTtFi7j1jFVuAyH5eejLNnNJxFziS0FMYj0uLdj6lqkEO+txlYMXhUG8/k/ZKXC3Ur9Em2/MCAYZB+qFw3DBe7OZcxEk=</SignatureValue>
    			<KeyInfo>
    				<X509Data>
    					<X509IssuerSerial>
    						<X509IssuerName>CN=Correo Uruguayo - CA, OU=SERVICIOS ELECTRONICOS, O=ADMINISTRACION NACIONAL DE CORREOS, C=UY</X509IssuerName>
    						<X509SerialNumber>155761856642617054135126896023459966393</X509SerialNumber>
    					</X509IssuerSerial>
    				</X509Data>
    			</KeyInfo>
    		</Signature>
    	</ns0:CFE>
    	<ns0:CFE version="1.0" xmlns:ns0="http://cfe.dgi.gub.uy">
    		<ns0:eTck>
    			<ns0:TmstFirma>2016-07-19T15:56:20-03:00</ns0:TmstFirma>
    		</ns0:eTck>
    		<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="">
    					<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>p1VrpYT0zI7huek2QhjKTGbCBsY=</DigestValue>
    				</Reference>
    			</SignedInfo>
    			<SignatureValue>Ad2/KMLEZgYPxlDVBUenLJ1L/AGYd9cskYzk09vJr2e6qoO/y6Swt5J5eN2ruPpNDj5HK80Ric+IiEDUdLEjBaveg/6Ao7v8v+biDUWCii7uWhGZ8wfyyEXbcrsZ+oATMmn0g36JWI3nFMkPlTkKvIIGJHPJR8xIQxcOI3vVgr0=</SignatureValue>
    			<KeyInfo>
    				<X509Data>
    					<X509IssuerSerial>
    						<X509IssuerName>CN=Correo Uruguayo - CA, OU=SERVICIOS ELECTRONICOS, O=ADMINISTRACION NACIONAL DE CORREOS, C=UY</X509IssuerName>
    						<X509SerialNumber>155761856642617054135126896023459966393</X509SerialNumber>
    					</X509IssuerSerial>
    				</X509Data>
    			</KeyInfo>
    		</Signature>
    	</ns0:CFE>
    

    Having spoken with the institution that receives and validates the xml (They practically have no idea how it works.
    ), I think if i sign an CFE, the digest value must be generated by the canonization of the subsection of that CFE.

    So if then i use the chillkat to comprobate if digest value is correct i only should pass a signed subsecciton? I'm not entirely sure how to do it with the library.

    I appreciate your understanding for my lack of knowledge on the subject. Any other information you need that may help understand the problem, please ask me.

  4. srd90 commented on May 29, 2024

    @srd90

    Yesterday i was trying to replicate your recommendations and i didn't get the digest value error anymore, but the signature still is invalid for some reason that i cant find. I used your generated certificate and private key too, but the result was the same when i use chillket to test.
>
    Does anyone know why this could be happening?

    Chilkat doesn't have your private key's public certificate which it could use to verify signature.

    Use some other online service or use some other tool like:

    xmlsec1 --verify ...

    (I don't have time to lookup and provide rest of options for that)

    Having spoken with the institution that receives and validates the xml (They practically have no idea how it works.) ...
    ...

    I get a feeling that no-one knows what proper outcome should be in your application's case. I.e. admins at the receiving side cannot provide you spec and therefore they are also unable to check that you are signing stuff correctly and that they are performing proper validation of input.

    IMHO xml-crypto's bug ticket is not correct place to have this discussion. Instead of having this bug ticket #472 this should have been discussion.

  5. locked and limited conversation to collaborators on May 29, 2024
  6. converted this issue into a discussion #473 on May 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions