Digital Signature Workflows in C# and VB.NET

Certificate (Author) Signature

With GemBox.Pdf, you can add a digital signature with an AuthorPermission specifying what actions are permitted after certifying.

The following example shows how to add a digital signature which is valid even when modifying the document's form fields.

PDF signature with FillForm access permissions
Screenshot of PDF with valid signature and modified field value
Upload your file (Drag file here)
using System;
using GemBox.Pdf;
using GemBox.Pdf.Security;
using GemBox.Pdf.Forms;

class Program
{
    static void Main()
    {
        // If using the Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");

        // Create signed document with author permission.
        using (var document = PdfDocument.Load("%InputFileName%"))
        {
            var textField = document.Form.Fields.AddText(document.Pages[0], 50, 530, 200, 20);
            textField.Name = "Field1";
            textField.Value = "Value before signing";

            var signatureField = document.Form.Fields.AddSignature(document.Pages[0], 300, 500, 250, 50);
            signatureField.Name = "Signature1";

            var digitalId = new PdfDigitalId("%InputDigitalId[0]%", "GemBoxPassword");
            var signer = new PdfSigner(digitalId);

            // Specify a certification signature with actions that are permitted after certifying the document.
            signer.AuthorPermission = PdfUserAccessPermissions.FillForm;

            // Adobe Acrobat Reader currently doesn't download the certificate chain
            // so we will also embed a certificate of intermediate Certificate Authority in the signature.
            // (see https://community.adobe.com/t5/acrobat/signature-validation-using-aia-extension-not-enabled-by-default/td-p/10729647)
            signer.ValidationInfo = new PdfSignatureValidationInfo(new PdfCertificate[] { new PdfCertificate("%InputDigitalId[1]%") }, null, null);

            signatureField.Sign(signer);

            document.Save("SignatureWithFillFormAccess.pdf");
        }

        // We're modifying the field's value of the signed document,
        // but the signature will remain valid because of the specified PdfUserAccessPermissions.FillForm.
        using (var document = PdfDocument.Load("SignatureWithFillFormAccess.pdf"))
        {
            var textField = (PdfTextField)document.Form.Fields["Field1"];
            textField.Value = "Value after signing";
            document.Save();
        }
    }
}
Imports System
Imports GemBox.Pdf
Imports GemBox.Pdf.Security
Imports GemBox.Pdf.Forms

Module Program

    Sub Main()

        ' If using the Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")

        ' Create signed document with author permission.
        Using document = PdfDocument.Load("%InputFileName%")
            Dim textField = document.Form.Fields.AddText(document.Pages(0), 50, 530, 200, 20)
            textField.Name = "Field1"
            textField.Value = "Value before signing"

            Dim signatureField = document.Form.Fields.AddSignature(document.Pages(0), 300, 500, 250, 50)
            signatureField.Name = "Signature1"

            Dim digitalId = New PdfDigitalId("%InputDigitalId[0]%", "GemBoxPassword")
            Dim signer = New PdfSigner(digitalId)

            ' Specify a certification signature with actions that are permitted after certifying the document.
            signer.AuthorPermission = PdfUserAccessPermissions.FillForm

            ' Adobe Acrobat Reader currently doesn't download the certificate chain
            ' so we will also embed a certificate of intermediate Certificate Authority in the signature.
            ' (see https://community.adobe.com/t5/acrobat/signature-validation-using-aia-extension-not-enabled-by-default/td-p/10729647)
            signer.ValidationInfo = New PdfSignatureValidationInfo(New PdfCertificate() {New PdfCertificate("%InputDigitalId[1]%")}, Nothing, Nothing)

            signatureField.Sign(signer)

            document.Save("SignatureWithFillFormAccess.pdf")
        End Using

        ' We're modifying the field's value of the signed document,
        ' but the signature will remain valid because of the specified PdfUserAccessPermissions.FillForm.
        Using document = PdfDocument.Load("SignatureWithFillFormAccess.pdf")
            Dim textField = DirectCast(document.Form.Fields("Field1"), PdfTextField)
            textField.Value = "Value after signing"
            document.Save()
        End Using

    End Sub
End Module

Signature Locks

The following example shows how to add a digital signature with a set of form fields whose change invalidates the signature. You can add locked fields by using the PdfSignatureField.SetLockedFields methods.

PDF signature with locked field
Screenshot of signed PDF with locked field
Upload your file (Drag file here)
using System;
using GemBox.Pdf;
using GemBox.Pdf.Security;
using GemBox.Pdf.Forms;

class Program
{
    static void Main()
    {
        // If using the Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");

        using (var document = PdfDocument.Load("%InputFileName%"))
        {
            var textField1 = document.Form.Fields.AddText(document.Pages[0], 50, 530, 200, 20);
            textField1.Name = "Text1";
            textField1.Value = "If changed signature is invalid";

            var textField2 = document.Form.Fields.AddText(document.Pages[0], 50, 480, 200, 20);
            textField2.Name = "Text2";
            textField2.Value = "If changed signature is still valid";

            var signatureField = document.Form.Fields.AddSignature(document.Pages[0], 300, 500, 250, 50);
            signatureField.Name = "Signature1";
            signatureField.SetLockedFields(textField1);

            var digitalId = new PdfDigitalId("%InputDigitalId[0]%", "GemBoxPassword");
            var signer = new PdfSigner(digitalId);

            // Adobe Acrobat Reader currently doesn't download the certificate chain
            // so we will also embed a certificate of intermediate Certificate Authority in the signature.
            // (see https://community.adobe.com/t5/acrobat/signature-validation-using-aia-extension-not-enabled-by-default/td-p/10729647)
            signer.ValidationInfo = new PdfSignatureValidationInfo(new PdfCertificate[] { new PdfCertificate("%InputDigitalId[1]%") }, null, null);

            signatureField.Sign(signer);

            document.Save("SignatureWithLockedFields.pdf");
        }
    }
}
Imports System
Imports GemBox.Pdf
Imports GemBox.Pdf.Security
Imports GemBox.Pdf.Forms

Module Program

    Sub Main()

        ' If using the Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")

        Using document = PdfDocument.Load("%InputFileName%")

            Dim textField1 = document.Form.Fields.AddText(document.Pages(0), 50, 530, 200, 20)
            textField1.Name = "Text1"
            textField1.Value = "If changed signature is invalid"

            Dim textField2 = document.Form.Fields.AddText(document.Pages(0), 50, 480, 200, 20)
            textField2.Name = "Text2"
            textField2.Value = "If changed signature is still valid"

            Dim signatureField = document.Form.Fields.AddSignature(document.Pages(0), 300, 500, 250, 50)
            signatureField.Name = "Signature1"
            signatureField.SetLockedFields(textField1)

            Dim digitalId = New PdfDigitalId("%InputDigitalId[0]%", "GemBoxPassword")
            Dim signer = New PdfSigner(digitalId)

            ' Adobe Acrobat Reader currently doesn't download the certificate chain
            ' so we will also embed a certificate of intermediate Certificate Authority in the signature.
            ' (see https://community.adobe.com/t5/acrobat/signature-validation-using-aia-extension-not-enabled-by-default/td-p/10729647)
            signer.ValidationInfo = New PdfSignatureValidationInfo(New PdfCertificate() {New PdfCertificate("%InputDigitalId[1]%")}, Nothing, Nothing)

            signatureField.Sign(signer)

            document.Save("SignatureWithLockedFields.pdf")

        End Using
    End Sub
End Module

Signatures Workflow

You can create a complete signature workflow by combining the above two examples. First, the document is signed with the author's signature, then the signer fills the dedicated form fields and signs the document with their approval signature.

PDF with certifying and approval signatures
Screenshot of PDF signed by certifying and approval signatures
Upload your file (Drag file here)
using System;
using GemBox.Pdf;
using GemBox.Pdf.Security;
using GemBox.Pdf.Forms;

class Program
{
    static void Main()
    {
        // If using the Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");

        using (var document = PdfDocument.Load("%InputFileName%"))
        {
            var textField = document.Form.Fields.AddText(document.Pages[0], 50, 530, 200, 20);
            textField.Name = "Field1";
            textField.Value = "Should be filled by the signer";

            // Signature field that is signed with the author permission.
            var authorSignatureField = document.Form.Fields.AddSignature();
            authorSignatureField.Name = "AuthorSignature";

            // Signature field that will be signed by another signer.
            var signatureField = document.Form.Fields.AddSignature(document.Pages[0], 300, 500, 250, 50);
            signatureField.Name = "Signature1";
            signatureField.SetLockedFields(textField);
            // After this signature field is signed, the document is final.
            signatureField.LockedFields.Permission = PdfUserAccessPermissions.None;

            var certifyingDigitalId = new PdfDigitalId("%InputDigitalId1[0]%", "GemBoxPassword");
            var authorSigner = new PdfSigner(certifyingDigitalId);

            // Specify a certification signature with actions that are permitted after certifying the document.
            authorSigner.AuthorPermission = PdfUserAccessPermissions.FillForm;

            // Adobe Acrobat Reader currently doesn't download the certificate chain
            // so we will also embed a certificate of intermediate Certificate Authority in the signature.
            // (see https://community.adobe.com/t5/acrobat/signature-validation-using-aia-extension-not-enabled-by-default/td-p/10729647)
            authorSigner.ValidationInfo = new PdfSignatureValidationInfo(new PdfCertificate[] { new PdfCertificate("%InputDigitalId1[1]%") }, null, null);

            authorSignatureField.Sign(authorSigner);

            // Finish first signing of a PDF file.
            document.Save("CertificateAndApprovalSignaturesWorkflow.pdf");

            // Another signer fills its text field.
            textField.Value = "Filled by another signer";

            // And signs on its signature field thus making its text field locked.
            var approvalDigitalId = new PdfDigitalId("%InputDigitalId2[0]%", "GemBoxPassword");
            var signer = new PdfSigner(approvalDigitalId);
            // Adobe Acrobat Reader currently doesn't download the certificate chain
            // so we will also embed a certificate of intermediate Certificate Authority in the signature.
            // (see https://community.adobe.com/t5/acrobat/signature-validation-using-aia-extension-not-enabled-by-default/td-p/10729647)
            signer.ValidationInfo = new PdfSignatureValidationInfo(new PdfCertificate[] { new PdfCertificate("%InputDigitalId2[1]%") }, null, null);
            signatureField.Sign(signer);

            // Finish second signing of the same PDF file.
            document.Save();
        }
    }
}
Imports System
Imports GemBox.Pdf
Imports GemBox.Pdf.Security
Imports GemBox.Pdf.Forms

Module Program

    Sub Main()

        ' If using the Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")

        Using document = PdfDocument.Load("%InputFileName%")
            Dim textField = document.Form.Fields.AddText(document.Pages(0), 50, 530, 200, 20)
            textField.Name = "Field1"
            textField.Value = "Should be filled by the signer"

            ' Signature field that is signed with the author permission.
            Dim authorSignatureField = document.Form.Fields.AddSignature()
            authorSignatureField.Name = "AuthorSignature"

            ' Signature field that will be signed by another signer.
            Dim signatureField = document.Form.Fields.AddSignature(document.Pages(0), 300, 500, 250, 50)
            signatureField.Name = "Signature1"
            signatureField.SetLockedFields(textField)
            ' After this signature field is signed, the document is final.
            signatureField.LockedFields.Permission = PdfUserAccessPermissions.None

            Dim certifyingDigitalId = New PdfDigitalId("%InputDigitalId1[0]%", "GemBoxPassword")
            Dim authorSigner = New PdfSigner(certifyingDigitalId)

            ' Adobe Acrobat Reader currently doesn't download the certificate chain
            ' so we will also embed a certificate of intermediate Certificate Authority in the signature.
            ' (see https://community.adobe.com/t5/acrobat/signature-validation-using-aia-extension-not-enabled-by-default/td-p/10729647)
            authorSigner.ValidationInfo = New PdfSignatureValidationInfo(New PdfCertificate() {New PdfCertificate("%InputDigitalId1[1]%")}, Nothing, Nothing)

            authorSignatureField.Sign(authorSigner)

            ' Finish first signing of a PDF file.
            document.Save("CertificateAndApprovalSignaturesWorkflow.pdf")

            ' Another signer fills its text field.
            textField.Value = "Filled by another signer"

            ' And signs on its signature field thus making its text field locked.
            Dim approvalDigitalId = New PdfDigitalId("%InputDigitalId2[0]%", "GemBoxPassword")
            Dim signer = New PdfSigner(approvalDigitalId)
            ' Adobe Acrobat Reader currently doesn't download the certificate chain
            ' so we will also embed a certificate of intermediate Certificate Authority in the signature.
            ' (see https://community.adobe.com/t5/acrobat/signature-validation-using-aia-extension-not-enabled-by-default/td-p/10729647)
            signer.ValidationInfo = New PdfSignatureValidationInfo(New PdfCertificate() {New PdfCertificate("%InputDigitalId2[1]%")}, Nothing, Nothing)
            signatureField.Sign(signer)

            ' Finish second signing of the same PDF file.
            document.Save()
        End Using
    End Sub
End Module

Digital ID notes

Digital ID files used in the preceding examples are part of a simple Public Key Infrastructure (PKI) created just for this demonstration which contains the following hierarchy of certificates and CRLs:

To get a valid signature in your Adobe Acrobat Reader as seen in the screenshots above, you will have to add GemBoxCA.crt certificate to the list of Trusted Certificates using the following steps:

  1. Download GemBoxCA.crt certificate.
  2. Open Adobe Acrobat Reader, select Edit > Preferences > Signatures. In Identities & Trusted Certificates click More.
  3. Select Trusted Certificates and click Import. Browse to the downloaded GemBoxCA.crt certificate and click Import.
  4. Select the imported GemBoxCA <info@gemboxsofware.com> certificate, click Edit Trust and add a check-mark next to Use this certificate as a trusted root.
  5. You can now delete the downloaded GemBoxCA.crt certificate. You can always later remove GemBoxCA <info@gemboxsofware.com> from Trusted Certificates by selecting it from the list of Trusted Certificates and clicking Remove.

Otherwise, to get a valid signature in any Adobe Acrobat Reader, your digital ID would have to be an AATL-enabled signing credential.

See also


Next steps

GemBox.Pdf is a .NET component that enables developers to read, merge and split PDF files or execute low-level object manipulations from .NET applications in a simple and efficient way.

Download Buy