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

Adding a reference to the KeyInfo element #86

Open
Zephidel opened this issue Sep 28, 2019 · 1 comment
Open

Adding a reference to the KeyInfo element #86

Zephidel opened this issue Sep 28, 2019 · 1 comment

Comments

@Zephidel
Copy link

Zephidel commented Sep 28, 2019

Hello

I'm having a couple of problems right now and to be honest I don't know to solve them. I'm trying to sign an XML file and I'm still a bit new to this.

  1. The standard used for these xml files demands that on the KeyInfo element the only allowed value is the x509 certificate, ¿How can I make sure that xadesjs can create the KeyInfo element without the KeyValue element?.

  2. According to the standard established for this documents (Here in Colombia) it needs 3 references inside, I have 2 of them but I'm missing the third, a sha256 reference to the KeyInfo element (Algorithm = http://www.w3.org/2001/04/xmlenc#sha256).

Here is my sign method in NodeJs:

/**
 * @param {string} xmlString XML to sign
 * @param {string} certificate Base64 Certificate
 * @param {string} publicKeyPem Base64 PublicKey pem
 * @param {string} privateKeyPem Base64 PrivateKey pem
*/
const signXML = async (xmlString, certificate, publicKeyPem, privateKeyPem) => {
  try {
    const sha256 = "SHA-256";
    const algorithm = {
      name: "RSASSA-PKCS1-v1_5",
      hash: sha256,
      publicExponent: new Uint8Array([1, 0, 1]),
      modulusLength: 2048,
    }
    // Read cert
    // const certDer = Convert.FromBase64(certificate);

    // Read public key
    const publicKeyDer = Convert.FromBase64(privateKeyPem);
    const publicKey = await crypto.subtle.importKey("spki", publicKeyDer, algorithm, true, ["verify"]);

    // Read private key
    const keyDer = Convert.FromBase64(publicKeyPem);
    const key = await crypto.subtle.importKey("pkcs8", keyDer, algorithm, false, ["sign"]);

    // XAdES-EPES
    const xml = xades.Parse(xmlString);
    const xadesXml = new xades.SignedXml(xml);
    const x509 = certificate;
    const referenceId = "Signature-ddb543c7";

    // Set the policy values
    xadesXml.SignedProperties.SignedSignatureProperties.SignaturePolicyIdentifier.SignaturePolicyId.SigPolicyId.Identifier.Value = "https://facturaelectronica.dian.gov.co/politicadefirma/v1/politicadefirmav2.pdf";
    xadesXml.SignedProperties.SignedSignatureProperties.SignaturePolicyIdentifier.SignaturePolicyId.SigPolicyHash.DigestMethod.Algorithm = "http://www.w3.org/2001/04/xmlenc#sha256";
    xadesXml.SignedProperties.SignedSignatureProperties.SignaturePolicyIdentifier.SignaturePolicyId.SigPolicyHash.DigestValue = [116, 202, 12, 190, 215, 6, 229, 162, 51, 129, 138, 52, 180, 139, 18, 65, 229, 73, 4, 57, 212, 157, 244, 142, 124, 26, 113, 94, 185, 168, 175, 70];

    // Create signature
    const signature = await xadesXml.Sign(   // Signing document
      algorithm,                             // algorithm
      key,                                   // key
      xml,                                   // document
      {                                      // options
        keyValue: publicKey,
        references: [
          {
            id: "xmldsig-0e79b719-635c-476f-a59e-8ac3ba14365d-ref0",
            uri: "",
            hash: sha256,
            transforms: ["enveloped"]
          },
        ],
        signerRole: {
          claimed: ["Supplier"]
        },
        x509: [x509],
        signingCertificate: x509,
    });

    // add Id to Signature
    const signatureXml = signature.GetXml();
    signatureXml.setAttribute("Id", referenceId);

    const xmlElem = xml.getElementById(referenceId);

    if (!xmlElem) {
      throw new Error("Cannot get XML element by Id `Signature-ddb543c7-ea0c-4b00-95b9-d4bfa2b4e411`");
    }

    // append signature
    xmlElem.appendChild(signature.GetXml());

    // serialize XML
    const sXML = xmlCore.Stringify(xml);
    const signedXml = Buffer.from(sXML).toString().replace(" id=\"Signature-ddb543c7\"", "");//"base64");
    return signedXml;

  } catch (err) {
    throw err;
  }
}

(Based on the solution by Andres Castillo @aazcast)

@microshine
Copy link
Contributor

xadesjs classes describe XML schema. You can change values without getElementById. For examples see apply functions

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