With WebCrypto API evolving and being supported by Chrome and Firefox, I would like to use it for digitally signing a PDF document. There is not much of literature around, but I found some examples [1] and a library called PKI.js [2]. In the examples, the signing process is described, but in the end, a signature is returned. I would expect my Base64 PDF file returned again in a signed Base64 string, but sadly, this is not what happens. PKI.js too, to my knowledge, does not provide a way to sign my Base64 PDF.
Is there a way to sign a PDF with JavaScript and the WebCrypto API only? The private key can be entered in a <textarea>
or, even better, stored in the certificate settings of the browser.
Base64 PDF (from REST API) → Sign with JS & certificate → Signed Base64 PDF (send to REST)
Apparently JavaScript code in PDFs is frequently called AcroJS or Acrobat JavaScript. This can be used for tracking! Putting together PDF and javascript functionalities is the classic recipe to make the usual can of worms.
Right-click (or Ctrl-click) on the PDF file you need to sign. Hover your cursor over "Open with" and click on "Adobe Acrobat Reader." Click on the Fill & Sign icon, which is represented by a calligraphy pen. Click "Sign," then click "Add Signature." If you want to add your initials instead, click "Add Initials."
Disclosure: I work for CISPL.
As of now, WebCrypto API does not provide access to (Windows) or any other Key stores or local crypto USB/Smartcard device.
Also in most of the signing scenarios, for requirement to protect pdf file within the server boundaries, its not recommended to send complete pdf file to browser or to signing API server.
Thus, its good practice, to create hash of PDF for signing, send hash to browser and use javascript through browser extension to access some application running on local system to access local keystore (or USB/Smartcard) and produce the signature and send back (PKCS7 or CMS container in case of PDF signing) to server where the signature may be injected back to PDF from which hash was created for signing and was sent to browser or to signing api server.
For browser based signing scenarios, my company provides one such free Browser extension Signer.Digital and .NET library required on server. Local system (host running behind the chrome browser on windows) may be downloaded from cNET Download site Installing this host and restarting Chrome will automatically add Signer.Digital Chrome Extension and/or Signer.Digital Firefox Extension
The actual working of this extension is illustrated here along with complete code walk through and download link to working sample VS 2015 project source code.
Javascript to call method from extension:
//Calculate Sign for the Hash by Calling function from Extension SignerDigital
SignerDigital.signPdfHash(hash, $("#CertThumbPrint").val(), "SHA-256") //or "SHA256"
//SignerDigitial.signHashCAdESBr method may be used for producing ICP-Brazil Signature
.then(
function (signDataResp) {
//Send signDataResp to Server
},
function (errmsg) {
//Send errmsg to server or display the result in browser.
}
);
If success, returns Base64 encoded pkcs7 signature - use suitable library or one provided by Signer.Digital to inject sign to pdf
If Failed, returns error msg starting with "SDHost Error:"
JULY 2022: Added method signCAdESBr to sign PDF or content as per ICP-Brazil standard and method signCAdESEg to sign as per Egypt ITIDA CAdES-BES.
There is PDFSign.js, a library that can sign a PDF file in the browser. It uses forge though for the signature. If PKI.js supports detached pkcs7 signatures, then it should be easy to replace forge.
It is technically possible to do this, in-fact it is one of the scenarios we had in mind when we made PKIjs (which is why there is this sample) - https://pkijs.org/examples/PDFexample.html
That said to do signing requires working with the PDF structure itself, which either requires a custom parser or modifications to an existing one (pdfjs for example).
Long story short, signing a PDF in browser will take a lot of work, it is something we are working on though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With