PDF digital signature with PKCS#11 (Cryptoki) device
The following example shows how to digitally sign a PDF file using a PKCS#11/Cryptoki device in C# or VB.NET, using the GemBox.Pdf component.
using GemBox.Pdf;
using GemBox.Pdf.Forms;
using GemBox.Pdf.Security;
using System;
using System.IO;
using System.Linq;
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 the 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 GemBox.Pdf
Imports GemBox.Pdf.Forms
Imports GemBox.Pdf.Security
Imports System
Imports System.IO
Imports System.Linq
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 the 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
Before reviewing the output of the following example in your Adobe Acrobat Reader, please read the Digital ID notes.
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, your digital ID would have to be an AATL-enabled signing credential to get a valid signature in any Adobe Acrobat Reader.Digital ID notes