Available Now: Explore our latest release with enhanced accessibility and powerful IDP features
By Andrew Varley, Josh Coffey | 2023 Aug 11
5 min
Tags
digital signature
javascript
node.js
Few things are as ubiquitous as Digital Signatures these days, and yet most documents are still signed with physical pens and paper in the world. As more Enterprise processes digitize, the growth in digital signatures will continue to explode, and making sure your application supports this need is more critical than ever. Besides the obvious benefits of being able to sign on a computer, there are several other advantages of Digital signatures, the electronic equivalents of physical or ink-and-paper signatures, such as:
The Apryse SDK is a powerful tool that can be used to create and manage digital signatures. It includes a number of benefits, such as:
Ensure Legal Compliance and Secure Your Documents - Discover the Benefits of PDF/A and Digital Signatures
In our Ultimate Guide to Digital Signatures, we looked at each area of the digital signature technology stack and how the Apryse Developer Suite can solve your signature use cases. We’ll give a short overview here, though you should refer to that article for the full story since this blog will focus on the actual nuts and bolts of signing a PDF in JavaScript with our Node.js SDK.
Before we begin, you should know there is an important distinction between e-Signatures and Digital Signatures.
E-signatures are electronic annotations that appear in a document. They do not contain any additional identifiable information about the creator other than an author field, which can be altered.
Digital signatures are a more secure form of electronic signature. They use a cryptographic algorithm to uniquely identify the author of a document. Any alterations to the document, including the annotations or e-signature, will result in an invalid digital signature validation.
Here is a table that summarizes the key differences between e-signatures and digital signatures:
Feature: Information about creator Security Tamper resistance Legal validity | E-signature Author field only Less secure Can be altered Varies by jurisdiction | Digital signature Author's public key More secure Can't be altered More widely accepted |
---|
With that out of the way, we’ll now walk through how to add an approval signature field and digitally sign it all using Apryse’s Node.js SDK.
To start, head over to our documentation and download the latest SDK build and test files for your operating system. Next, you’ll want to Initialize the Apryse SDK with our trial license, which you can get for free after downloading, see the Get Started link for more details.
To begin, we need to add an Approval Field to the document, which is used to indicate to the next participant in the process where to digitally sign the field.
Original file without a signature field.
We want to put a signature box directly on the file, which will be a rectangle with a height and width set in pixels. This code places the signature annotation onto the PDF and saves the output for the next step in the process.
const { PDFNet } = require('@pdftron/pdfnet-node');
// Initialize PDFNet
PDFNet.initialize(licenseKey);
const inputFilePath = './pdf-sample.pdf';
const outputFilePath = './pdf-sample-with-signature.pdf';
// Open an existing PDF document
const doc = await PDFNet.PDFDoc.createFromFilePath(inputFilePath);
// Create a signature field that we can sign
const signatureWidget = await PDFNet.SignatureWidget.create(doc, PDFNet.Rect(300, 287, 376, 306), 'ApryseApprovalSig');
// Add the signature widget to page 1 of the PDF
const page1 = await doc.getPage(1);
await page1.annotPushBack(signatureWidget);
// Save a new PDF with the signature field
await doc.save(outputFilePath, PDFNet.SDFDoc.SaveOptions.e_remove_unused);
In certain scenarios involving a third-party entity between a sender and other parties, the use of a Certificate Authority becomes essential. However, when a CA is unavailable or not required for your use case, a self-signed certificate can be utilized instead, as demonstrated in our digital signature sample or WebViewer demo. Please note that Apryse does not offer CA services; therefore, it is the responsibility of users to incorporate a CA into their digital signature workflow if required for their specific use cases.
For our example, we’ll add our certificate into the PDF. We need to first add a text field that can be used to lock the field permissions. It’s also important to add your digital signature field into a Widget, as some PDF Editors will not properly show that field to the user in a friendly way. We can make the dimensions of the widget 0 and add a NoPrint/Invisible flag which will make it invisible. We then set the field-level permissions to be restricted and attach our logo to the widget. Finally, we can add additional information into the signature dictionary of the PDF, including HQ headquarters, website, or contact information.
Create, annotate, and digitally sign PDFs in your browser with Apryse WebViewer. Start your document workflow now!
// Open existing PDF.
const doc = await PDFNet.PDFDoc.createFromFilePath(in_docpath);
doc.initSecurityHandler();
const page1 = await doc.getPage(1);
// Create a text field that we can lock using the field permissions feature.
const annot1 = await PDFNet.TextWidget.create(doc, new PDFNet.Rect(143, 440, 350, 460), 'asdf_test_field');
await page1.annotPushBack(annot1);
/* Create a new signature form field in the PDFDoc. The name argument is optional;
leaving it empty causes it to be auto-generated. However, you may need the name for later.
Acrobat doesn't show digsigfield in side panel if it's without a widget. Using a
Rect with 0 width and 0 height, or setting the NoPrint/Invisible flags makes it invisible. */
const certification_sig_field = await doc.createDigitalSignatureField(in_cert_field_name);
const widgetAnnot = await PDFNet.SignatureWidget.createWithDigitalSignatureField(doc, new PDFNet.Rect(143, 287, 219, 306), certification_sig_field);
await page1.annotPushBack(widgetAnnot);
// (OPTIONAL) Add an appearance to the signature field.
const img = await PDFNet.Image.createFromFile(doc, in_appearance_image_path);
await widgetAnnot.createSignatureAppearance(img);
// Prepare the document locking permission level. It will be applied upon document certification.
await certification_sig_field.setDocumentPermissions(PDFNet.DigitalSignatureField.DocumentPermissions.e_annotating_formfilling_signing_allowed);
// Prepare to lock the text field that we created earlier.
var fields_to_lock = ['asdf_test_field'];
await certification_sig_field.setFieldPermissions(PDFNet.DigitalSignatureField.FieldPermissions.e_include, fields_to_lock);
await certification_sig_field.certifyOnNextSave(in_private_key_file_path, in_keyfile_password);
// (OPTIONAL) Add more information to the signature dictionary.
await certification_sig_field.setLocation('Denver, CO');
await certification_sig_field.setReason('Document certification.');
await certification_sig_field.setContactInfo('www.apryse.com');
// Save the PDFDoc. Once the method below is called, PDFNet will also sign the document using the information provided.
await doc.save(in_outpath, 0);
Now that the document has an approval field and has been certified, it’s time to digitally sign the PDF. We are using an image of our signature in this example and applying it to the widget and field that we created for the signer. In more complex examples or multi-signature PDF portfolios or pages, we can loop through the DigitalSignatureField to apply the same or different sets of signatures.
// Open an existing PDF
const doc = await PDFNet.PDFDoc.createFromFilePath(in_docpath);
doc.initSecurityHandler();
// Retrieve the unsigned approval signature field.
const found_approval_field = await doc.getField(in_approval_field_name);
const found_approval_signature_digsig_field = await PDFNet.DigitalSignatureField.createFromField(found_approval_field);
// (OPTIONAL) Add an appearance to the signature field.
const img = await PDFNet.Image.createFromFile(doc, in_appearance_img_path);
const found_approval_signature_widget = await PDFNet.SignatureWidget.createFromObj(await found_approval_field.getSDFObj());
await found_approval_signature_widget.createSignatureAppearance(img);
// Prepare the signature and signature handler for signing.
await found_approval_signature_digsig_field.signOnNextSave(in_private_key_file_path, in_keyfile_password);
// The actual approval signing will be done during the following incremental save operation.
await doc.save(in_outpath, PDFNet.SDFDoc.SaveOptions.e_incremental);
The final version of the document now has a digitally trusted signature that can be verified to ensure the document has not been tampered with since being signed.
Verified using Apryse’s WebViewer.
And there you have it, a digitally signed and verified PDF document! We hope you have found this guide useful, and you can check out the documentation for our JavaScript and Node.js Digital Signature Library. Don’t forget you can also reach out to us on Discord if you have any issues.
Tags
digital signature
javascript
node.js
Andrew Varley
Chief Product Officer
Josh Coffey
Chief Technology Officer
Share this post
PRODUCTS
Enterprise
Small Business
Popular Content