xadesjs
xadesjs copied to clipboard
Adding a reference to the KeyInfo element
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.
-
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?.
-
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)
xadesjs
classes describe XML schema. You can change values without getElementById
. For examples see apply functions