PDF digital signature with PKCS#11 (Cryptoki) device in C# and VB.NET

PKCS#11 is one of the Public-Key Cryptography Standards (PKCS) that defines a platform-independent API (called "Cryptoki") to cryptographic devices, such as hardware security modules (HSM) and smart cards.

With GemBox.Pdf, you can digitally sign PDF files using a PKCS#11/Cryptoki device that conforms to PKCS#11 specification in your C# or VB.NET application.

Before reviewing the output of the following example in your Adobe Acrobat Reader, please read the Digital ID notes.

Before running the following example on your machine, please read the Dependencies notes.

The following example shows how to digitally sign a PDF file using a PKCS#11/Cryptoki device.

PDF file digitally signed with PKCS#11/Cryptoki device using GemBox.Pdf
Screenshot of PDF file digitally signed with PKCS#11/Cryptoki device using GemBox.Pdf
Upload your file (Drag file here)
using System;
using System.IO;
using System.Linq;
using GemBox.Pdf;
using GemBox.Pdf.Forms;
using GemBox.Pdf.Security;

class Program
{
    static void Main()
    {
        // Extract GemBoxPkcs11SoftwareModule from ZIP archive and setup environment variable with path to configuration file.
        // Required only for SoftHSM device used in this example. Not required for yours PKCS#11/Cryptoki device.
        var pkcs11SoftwareModuleDirectory = "GemBoxPkcs11SoftwareModule";
        System.IO.Compression.ZipFile.ExtractToDirectory("%#GemBoxPkcs11SoftwareModule.zip%", pkcs11SoftwareModuleDirectory);
        Environment.SetEnvironmentVariable("SOFTHSM2_CONF", Path.Combine(pkcs11SoftwareModuleDirectory, "softhsm2.conf"));

        // Specify path to PKCS#11/Cryptoki library, depending on the runtime architecture (64-bit or 32-bit).
        var libraryPath = Path.Combine(pkcs11SoftwareModuleDirectory, IntPtr.Size == 8 ? "softhsm2-x64.dll" : "softhsm2.dll");

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

        using (var pkcs11Module = new PdfPkcs11Module(libraryPath))
        {
            // Get a token from PKCS#11/Cryptoki device.
            var token = pkcs11Module.Tokens.Single(t => t.TokenLabel == "%InputDigitalId[0]%");

            // Login to the token to get access to protected cryptographic functions.
            token.Login("%InputDigitalId[1]%");

            // Get a digital ID from PKCS#11/Cryptoki device token.
            var digitalId = token.DigitalIds.Single(id => id.Certificate.SubjectCommonName == "%InputDigitalId[2]%");

            using (var document = PdfDocument.Load("%InputFileName%"))
            {
                // Add a visible signature field to the first page of the PDF document.
                var signatureField = document.Form.Fields.AddSignature(document.Pages[0], 300, 500, 250, 50);

                // Create a PDF signer that will create the digital signature.
                var signer = new PdfSigner(digitalId);

                // Adobe Acrobat Reader currently doesn't download certificate chain
                // so we will also embed 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)
                var intermediateCA = token.DigitalIds.Single(id => id.Certificate.SubjectCommonName == "%InputDigitalId[3]%").Certificate;
                signer.ValidationInfo = new PdfSignatureValidationInfo(new PdfCertificate[] { intermediateCA }, null, null);

                // Initiate signing of a PDF file with the specified signer.
                signatureField.Sign(signer);

                // Finish signing of a PDF file.
                document.Save("Digital Signature PKCS#11.pdf");
            }

            token.Logout();
        }
    }
}
Imports System
Imports System.IO
Imports System.Linq
Imports GemBox.Pdf
Imports GemBox.Pdf.Forms
Imports GemBox.Pdf.Security

Module Program

    Sub Main()

        ' Extract GemBoxPkcs11SoftwareModule from ZIP archive and setup environment variable with path to configuration file.
        ' Required only for SoftHSM device used in this example. Not required for yours PKCS#11/Cryptoki device.
        Dim pkcs11SoftwareModuleDirectory = "GemBoxPkcs11SoftwareModule"
        System.IO.Compression.ZipFile.ExtractToDirectory("%#GemBoxPkcs11SoftwareModule.zip%", pkcs11SoftwareModuleDirectory)
        Environment.SetEnvironmentVariable("SOFTHSM2_CONF", Path.Combine(pkcs11SoftwareModuleDirectory, "softhsm2.conf"))

        ' Specify path to PKCS#11/Cryptoki library, depending on the runtime architecture (64-bit or 32-bit).
        Dim libraryPath = Path.Combine(pkcs11SoftwareModuleDirectory, If(IntPtr.Size = 8, "softhsm2-x64.dll", "softhsm2.dll"))

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

        Using pkcs11Module = New PdfPkcs11Module(libraryPath)

            ' Get a token from PKCS#11/Cryptoki device.
            Dim token = pkcs11Module.Tokens.Single(Function(t) t.TokenLabel = "%InputDigitalId[0]%")

            ' Login to the token to get access to protected cryptographic functions.
            token.Login("%InputDigitalId[1]%")

            ' Get a digital ID from PKCS#11/Cryptoki device token.
            Dim digitalId = token.DigitalIds.Single(Function(id) id.Certificate.SubjectCommonName = "%InputDigitalId[2]%")

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

                ' Add a visible signature field to the first page of the PDF document.
                Dim signatureField = document.Form.Fields.AddSignature(document.Pages(0), 300, 500, 250, 50)

                ' Create a PDF signer that will create the digital signature.
                Dim signer = New PdfSigner(digitalId)

                ' Adobe Acrobat Reader currently doesn't download certificate chain
                ' so we will also embed 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)
                Dim intermediateCA = token.DigitalIds.Single(Function(id) id.Certificate.SubjectCommonName = "%InputDigitalId[3]%").Certificate
                signer.ValidationInfo = New PdfSignatureValidationInfo(New PdfCertificate() {intermediateCA}, Nothing, Nothing)

                ' Initiate signing of a PDF file with the specified signer.
                signatureField.Sign(signer)

                'Finish signing of a PDF file.
                document.Save("Digital Signature PKCS#11.pdf")
            End Using

            token.Logout()
        End Using
    End Sub
End Module

The PKCS#11/Cryptoki device used in the example is SoftHSM (software implementation of a generic cryptographic device with a PKCS#11 interface) configured to contain digital IDs and certificates described in the next subsection.

Digital ID notes

Digital IDs used in the preceding example are part of a simple Public Key Infrastructure (PKI) created just for this demonstration which contains the following hierarchy of certificates:

  • Root Certificate Authority certificate GemBoxCA.crt
    • Intermediate Certificate Authority certificate GemBoxRSA.crt
      • Digital ID GemBoxRSA4096 with 4096-bit RSA private key and certificate GemBoxRSA4096.crt (contained in the token labeled GemBoxRSAToken of GemBoxPkcs11SoftwareModule device)
    • Intermediate Certificate Authority certificate GemBoxECDsa.crt
      • Digital ID GemBoxECDsa521 with 521-bit Elliptic Curve (ECDsa) private key and certificate GemBoxECDsa521.crt (contained in the token labeled GemBoxECDsaToken of GemBoxPkcs11SoftwareModule device)

To get a valid signature in your Adobe Acrobat Reader as seen in the screenshot 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.

Dependencies notes

Except GemBox.Pdf, your project must reference the following NuGet packages:

Want more?

Next example GitHub

Check the next example or select an example from the menu. You can also download our examples from the GitHub.


Like it?

Download Buy

If you want to try the GemBox.Pdf yourself, you can download the free version. It delivers the same performance and set of features as the professional version, but with some operations limited. To remove the limitation, you need to purchase a license.