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.

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 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: 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: Otherwise, to get a valid signature in any Adobe Acrobat Reader, your digital ID would have to be an AATL-enabled signing credential. Except GemBox.Pdf, your project must reference the following NuGet packages:Digital ID notes
Dependencies notes