Available Now: Explore our latest release with enhanced accessibility and powerful IDP features

Adding a Digital Signature to a PDF in C# with the .Net SDK

By Andrew Varley, Josh Coffey | 2023 Aug 11

Sanity Image
Read time

5 min

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:

  • Authentication: A digital signature allows for the precise identification of the signer. When a signature is valid, you can safely assume that you know who signed the document.
  • Integrity: A digital signature allows users to easily validate whether the contents of a document have been changed since it was signed.
  • Non-repudiation: A digital signature ensures that the signer cannot deny that they signed the document.

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:

  • Import and export signature fields: The Apryse SDK can be used to import and export signature fields from XFDF/FDF files. This makes it easy to integrate with existing document workflows.
  • Built-in support for PKI signing: The Apryse SDK includes built-in support for PKI signing (and PFX digital certificates). This makes it easy to create secure and legally binding digital signatures.
  • Support for custom signature handlers: The Apryse SDK allows you to create custom signature handlers. This gives you the flexibility to customize the appearance and behavior of digital signatures.
  • Sign with images, ink annotations, or entirely custom appearances: The Apryse SDK allows you to sign documents with images, ink annotations, or entirely custom appearances. This gives you the freedom to create digital signatures that are both secure and visually appealing.

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 with our Python SDK.

Before we begin, you should know there is an important distinction between e-Signatures and Digital Signatures.

E-Signatures and Digital Signatures: What’s the Difference?

Copied to clipboard

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 Python SDK.

Setup for development

Copied to clipboard

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.

Adding a Digital Signature Approval Field

Copied to clipboard

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.

Blog image

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.

using (PDFDoc doc = new PDFDoc(input_path + "waiver.pdf")) 
{
    DigitalSignatureField approval_signature_field = doc.CreateDigitalSignatureField("ApryseApprovalSig");
    SignatureWidget widgetAnnotApproval = SignatureWidget.Create(doc, new Rect(300, 287, 376, 306), approval_signature_field);
    Page page1 = doc.GetPage(1);
    page1.AnnotPushBack(widgetAnnotApproval);
    doc.Save(output_path + "waiver_withApprovalField_output.pdf", SDFDoc.SaveOptions.e_remove_unused);
}
Blog image

Adding a Certified Signature Field to a PDF

Copied to clipboard

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.

using (PDFDoc doc = new PDFDoc(in_docpath))
{
    Page page1 = doc.GetPage(1);

    // Create a text field that we can lock using the field permissions feature.
    TextWidget annot1 = TextWidget.Create(doc, new Rect(143, 440, 350, 460), "asdf_test_field");
    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. */
    DigitalSignatureField certification_sig_field = doc.CreateDigitalSignatureField(in_cert_field_name);
    SignatureWidget widgetAnnot = SignatureWidget.Create(doc, new Rect(143, 287, 219, 306), certification_sig_field);
    page1.AnnotPushBack(widgetAnnot);

    // (OPTIONAL) Add an appearance to the signature field.
    Image img = Image.Create(doc, in_appearance_image_path);
    widgetAnnot.CreateSignatureAppearance(img);

    // Prepare the document locking permission level. It will be applied upon document certification.
    certification_sig_field.SetDocumentPermissions(DigitalSignatureField.DocumentPermissions.e_annotating_formfilling_signing_allowed);
    
    // Prepare to lock the text field that we created earlier.
    string[] fields_to_lock = new string[1];
    fields_to_lock[0] = "asdf_test_field";
    certification_sig_field.SetFieldPermissions(DigitalSignatureField.FieldPermissions.e_include, fields_to_lock);
    certification_sig_field.CertifyOnNextSave(in_private_key_file_path, in_keyfile_password);

    // (OPTIONAL) Add more information to the signature dictionary.
    certification_sig_field.SetLocation("Denver, CO");
    certification_sig_field.SetReason("Document certification.");
    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.
    doc.Save(in_outpath, 0);
}

Digitally Signing the PDF

Copied to clipboard

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.

using (PDFDoc doc = new PDFDoc(in_docpath))
{
    // Retrieve the unsigned approval signature field.
    Field found_approval_field = doc.GetField(in_approval_field_name);
    DigitalSignatureField found_approval_signature_digsig_field = new DigitalSignatureField(found_approval_field);
    
    // (OPTIONAL) Add an appearance to the signature field.
    Image img = Image.Create(doc, in_appearance_img_path);
    SignatureWidget found_approval_signature_widget = new SignatureWidget(found_approval_field.GetSDFObj());
    found_approval_signature_widget.CreateSignatureAppearance(img);

    // Prepare the signature and signature handler for signing.
    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.
    doc.Save(in_outpath, 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.

Blog image

Verified using Apryse’s WebViewer.

Conclusion

Copied to clipboard

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 Python Digital Signature Library. Don’t forget you can also reach out to us on Discord if you have any issues.

Sanity Image

Andrew Varley

Chief Product Officer

Sanity Image

Josh Coffey

Chief Technology Officer

Share this post

email
linkedIn
twitter