-
-
Save ronnycoding/d9b8c3cca1c7a76fcf02ad4c26d74bd9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require("fs"); | |
const WebCrypto = require("node-webcrypto-ossl"); | |
const xadesjs = require("xadesjs"); | |
const { XMLSerializer } = require("xmldom-alpha"); | |
const crypto = new WebCrypto(); | |
xadesjs.Application.setEngine("OpenSSL", crypto); | |
function preparePem(pem) { | |
return pem | |
// remove BEGIN/END | |
.replace(/-----(BEGIN|END)[\w\d\s]+-----/g, "") | |
// remove \r, \n | |
.replace(/[\r\n]/g, ""); | |
} | |
function pem2der(pem) { | |
pem = preparePem(pem); | |
// convert base64 to ArrayBuffer | |
return new Uint8Array(Buffer.from(pem, "base64")).buffer; | |
} | |
async function main() { | |
const hash = "SHA-256" | |
const alg = { | |
name: "RSASSA-PKCS1-v1_5", | |
hash, | |
modulusLength: 2048, | |
} | |
// Read cert | |
const certPem = fs.readFileSync("cert.pem", { encoding: "utf8" }); | |
const certDer = pem2der(certPem); | |
// Read key | |
const keyPem = fs.readFileSync("decrypted.pem", { encoding: "utf8" }); | |
const keyDer = pem2der(keyPem); | |
const key = await crypto.subtle.importKey("pkcs8", keyDer, alg, false, ["sign"]); | |
// XAdES-EPES | |
var contents = fs.readFileSync('./factura.xml', 'utf8'); | |
var xmlString = contents; | |
var xml = xadesjs.Parse(xmlString); | |
var xadesXml = new xadesjs.SignedXml(); | |
const x509 = preparePem(certPem); | |
console.log(x509); | |
const signature = await xadesXml.Sign( // Signing document | |
alg, // algorithm | |
key, // key | |
xml, // document | |
{ // options | |
references: [ | |
{ hash, transforms: ["c14n", "enveloped"] } | |
], | |
policy: { | |
hash, | |
identifier: { | |
value: "https://tribunet.hacienda.go.cr/docs/esquemas/2016/v4.1/Resolucion_Comprobantes_Electronicos_DGT-R-48-2016.pdf", | |
} | |
}, | |
productionPlace: { | |
country: "Costa Rica", | |
state: "San José", | |
city: "Aserrí", | |
code: "10601", | |
}, | |
x509: [x509], | |
signingCertificate: x509 | |
}); | |
// append signature | |
xml.documentElement.appendChild(signature.GetXml()); | |
// serialize XML | |
const oSerializer = new XMLSerializer(); | |
const sXML = oSerializer.serializeToString(xml); | |
console.log(sXML.toString()) | |
fs.unlinkSync("firmada.xml"); | |
fs.writeFile("firmada.xml", sXML.toString(), function(err) { | |
if(err) { | |
return console.log(err); | |
} | |
console.log("Factura guardada!"); | |
}); | |
} | |
main() | |
.catch((err) => { | |
console.error(err); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment