Get In Touch

Digital Signature process to sign XML File with Nodejs

XML sign using nodeJs:

  • You can get sample signature from any website who provide DSC .

The sample format should be in.pfx format because for application signing it’s thumb rule that you should have .pfx file and this pfx file will use tho sign both type of document xml and PDF.

The given website we have downloaded sample. You can go through it and download file and name will be document signer certificate.

https://www.e-mudhra.com/repository/

Once you will download you should have password to open and read certificate and other details.

Demo :emudhra

  • Once you will get this file then you need to upload your file in particular directory/bucket.

For uploading you can use same file upload process with given NPM package

https://www.npmjs.com/package/express-fileupload

  • Include this NPM Package

letforge = require(“node-forge”);

forge.options.usePureJavaScript = true; //For Javascript Strict Rule

 

  • Once you will upload your .pfx  file you need to pass the location of uploaded file.

request.body.data = This is the json data you are getting from front-end

Let uploadedPfxUrl = request.body.pfx_url

Now follow the given code and same use in your code

// get file into buffer from the uploaded bucket/Directory.

letcertificateFile = await axios.get(uploadedPfxUrl, {

responseType:”arraybuffer”,

});

Convert into base64

letreturnedB64 = Buffer.from(certificateFile.data).toString(“base64”);

 

Get P12Der

let p12Der = forge.util.decode64(returnedB64);

 

Convert into P12Asn1

let p12Asn1 = forge.asn1.fromDer(p12Der);

 

Get P12

let p12 = forge.pkcs12.pkcs12FromAsn1(

p12Asn1,

request.body.data.password //Pass your pfx password

);

 

// get the public key, the forge library I have included in top

Let certBags = p12.getBags({ bagType:forge.pki.oids.certBag });

// console.log(“certBags”, certBags);

//Get the private key

Let pkeyBags = p12.getBags({

bagType:forge.pki.oids.pkcs8ShroudedKeyBag,

});

 

It will return the array so you need to pass the value as per index

 

Let certBag = certBags[forge.pki.oids.certBag][0];

// console.log(“certBag”, certBag);

// fetching keyBag

Let keybag = pkeyBags[forge.pki.oids.pkcs8ShroudedKeyBag][0];

 

Pem Value public  and private get

Let privateKeyPem = forge.pki.privateKeyToPem(keybag.key);

// console.log(“privateKeyPem”, privateKeyPem);

// generate pem from cert

Let certificate = forge.pki.certificateToPem(certBag.cert); // with header and footer

 

//For XML value

 

letcertDer = forge.pki.pemToDer(certificate);

letp12b64 = forge.util.encode64(certDer.data); // without header and footer

 

//Base 64 Certificate Get

Let cert = forge.pki.certificateFromPem(certificate);

 

//Save the particular value from object that you will need to pass when you sign the xml file

Let email = cert.extensions.find((o) =>o.name === “subjectAltName”);

Const md = forge.md.sha1.create();

md.update(

forge.asn1.toDer(forge.pki.certificateToAsn1(cert)).getBytes()

);

//Thumb Print Get

Const hex = md.digest().toHex();

 

Let hexSignature = forge.util.bytesToHex(cert.signature);

// console.log(“hexSignature”, hexSignature);

Let certificateDataObj = {

validity:cert.validity,

partyName:cert.subject,

certificateNumber:cert.serialNumber,

certificateIssuer:cert.issuer,

email:email.altNames,

thumbPrint:hex,

certificate:p12b64,

// certificate: certificate,

signature:privateKeyPem,

};

return { certificateDataObj };

}

//Generate Modulus

 

// get public exponent & modulus as base64 encoded

Let modulus = forge.util.encode64(

forge.util.hexToBytes(forgePrivateKey.n.toString(16))

);

//Generate Exponent

Let exponent = forge.util.encode64(

forge.util.hexToBytes(forgePrivateKey.e.toString(16))

);

 

3)  Now reading part done so now you need to sign xml file.

Here, you need a reference tag to add signature,

Let xref = “.//*[local-name(.)=’TAG Name’]”;

 

Let xmlString = “ALL xml tag string”

Let pvtKey= You all ready have which you have read from .pfx file

Let pubKey = You all ready have which you have read from .pfx file

Let modulus = You all ready have which you have read from .pfx file

Let exponent = You all ready have which you have read from .pfx file

 

letsignXML = (xmlString, xmlRef, pvtKey, pubKey, modulus, exponent) => {

// instance for sign xml

letsig = newSignedXml();

// added xml node path &propoerties for sign

sig.addReference(

xmlRef,

[

“http://www.w3.org/2000/09/xmldsig#enveloped-signature”,

“http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments”,

],

“http://www.w3.org/2000/09/xmldsig#sha1”,

“”,

“”,

“”,

true

);

// putting algos for sign

sig.signatureAlgorithm = “http://www.w3.org/2000/09/xmldsig#rsa-sha1”;

sig.canonicalizationAlgorithm =

“http://www.w3.org/TR/2001/REC-xml-c14n-20010315”;

// added pvt key pem

sig.signingKey = pvtKey;

// added public key for verification

sig.keyInfoProvider = {

getKeyInfo: (key, prefix) => {

return`<X509Data><X509Certificate>${pubKey}</X509Certificate></X509Data><KeyValue><RSAKeyValue><Modulus>${modulus}</Modulus><Exponent>${exponent}</Exponent></RSAKeyValue></KeyValue>`;

},

};

//sign the xml doc with the data

sig.computeSignature(xmlString);

returnsig.getSignedXml(); // return signed xml file

};

Digital Signature process to sign XML File with nodejs:

  • Uploading and reading part you have to follow same process
  • Now you need to add signature, for signature you can use given library

https://www.npmjs.com/package/node-signpdf

Include this library as per given below

let forge = require(“node-forge”);

forge.options.usePureJavaScript = true;

const signer = require(“node-signpdf”).default;

  • You also need to get placeholder to add signature

Const signedDoc = signer.sign(pdfBufferToSign, pfxFileBuffer.data, {

passphrase:password,

});

Share

Add Your Comments

Your email address will not be published.