officefileapi-403721-pdf-document-api-examples-document-protection-how-to-use-a-certificate-from-a-hardware-device-to-sign-a-document.md
The PDF Document API allows you to retrieve a certificate from a hardware device (such as the Windows Certificate Store, SmartCard, USB Token). This example uses a certificate stored on a user’s machine. You can also adapt this solution to sign documents with certificates from any physical store.
View Example: PDF Document API - Sign a PDF document with a certificate stored on a hardware device
Obtain a certificate from a Windows certificate store. In this example, the X509Certificate2UI class object displays a system dialog. This dialog allows you to select an X.509 certificate installed on the current machine.
Tip
You can adapt this code to read a certificate from a SmartCard or USB Token: How to enter a PIN for an X509Certificate2 certificate programmatically when signing a PDF (in C#)
Pass the retrieved certificate to the Pkcs7Signer object constructor to create a PKCS#7 signature with the selected certificate. Call the PdfDocumentSigner.SaveDocument method to sign and save a document.
using DevExpress.Pdf;
using System;
using System.Diagnostics;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using DevExpress.Office.DigitalSignatures;
namespace SignPDFWithHardwareCertificate
{
class Program
{
static void Main(string[] args)
{
X509Certificate2 cert = GetCertificate();
if (cert != null)
{
SignPDF(cert);
}
else
Console.WriteLine("There are no installed certificates on this machine.");
}
static X509Certificate2 GetCertificate()
{
// Get a certificate from a Windows Store
X509Store store = new X509Store(StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
// Display a dialog box to select a certificate from the Windows Store
X509Certificate2Collection selectedCertificates =
X509Certificate2UI.SelectFromCollection(store.Certificates, null, null, X509SelectionFlag.SingleSelection);
// Get the first certificate that has a primary key
foreach (var certificate in selectedCertificates)
{
if (certificate.HasPrivateKey)
return certificate;
}
return null;
}
static void SignPDF(X509Certificate2 cert)
{
using (var signer = new PdfDocumentSigner(File.OpenRead("Demo.pdf")))
{
// Create a PKCS#7 signature
Pkcs7Signer pkcs7Signature = new Pkcs7Signer(cert, HashAlgorithmType.SHA256);
// Create a signature field on the first page
var signatureFieldInfo = new PdfSignatureFieldInfo(1);
// Specify the field's name and location
signatureFieldInfo.Name = "SignatureField";
signatureFieldInfo.SignatureBounds = new PdfRectangle(20, 20, 150, 150);
// Apply a signature to a newly created signature field
var cooperSignature = new PdfSignatureBuilder(pkcs7Signature, signatureFieldInfo);
cooperSignature.SetImageData(System.IO.File.ReadAllBytes("JaneCooper.jpg"));
// Sign and save the document
signer.SaveDocument("SignedDocument.pdf", cooperSignature);
}
Process.Start(new ProcessStartInfo("SignedDocument.pdf") { UseShellExecute = true });
}
}
}
Imports DevExpress.Pdf
Imports System
Imports System.Diagnostics
Imports System.IO
Imports System.Security.Cryptography.X509Certificates
Imports DevExpress.Office.DigitalSignatures
Namespace SignPDFWithHardwareCertificate
Friend Class Program
Shared Sub Main(ByVal args As String())
Dim cert As X509Certificate2 = GetCertificate()
If cert IsNot Nothing Then
SignPDF(cert)
Else
Console.WriteLine("There are no installed certificates on this machine.")
End If
End Sub
Private Shared Function GetCertificate() As X509Certificate2
' Get a certificate from a Windows Store
Dim store As X509Store = New X509Store(StoreLocation.CurrentUser)
store.Open(OpenFlags.ReadOnly Or OpenFlags.OpenExistingOnly)
' Display a dialog box to select a certificate from the Windows Store
Dim selectedCertificates As X509Certificate2Collection = X509Certificate2UI.SelectFromCollection(store.Certificates, Nothing, Nothing, X509SelectionFlag.SingleSelection)
' Get the first certificate that has a primary key
For Each certificate In selectedCertificates
If certificate.HasPrivateKey Then Return certificate
Next
Return Nothing
End Function
Private Shared Sub SignPDF(ByVal cert As X509Certificate2)
Using signer = New PdfDocumentSigner(File.OpenRead("Demo.pdf"))
' Create a PKCS#7 signature
Dim pkcs7Signature As Pkcs7Signer = New Pkcs7Signer(cert, HashAlgorithmType.SHA256)
' Create a signature field on the first page
Dim signatureFieldInfo = New PdfSignatureFieldInfo(1)
' Specify the field's name and location
signatureFieldInfo.Name = "SignatureField"
signatureFieldInfo.SignatureBounds = New PdfRectangle(20, 20, 150, 150)
' Apply a signature to a newly created signature field
Dim cooperSignature = New PdfSignatureBuilder(pkcs7Signature, signatureFieldInfo)
cooperSignature.SetImageData(File.ReadAllBytes("JaneCooper.jpg"))
' Sign and save the document
signer.SaveDocument("SignedDocument.pdf", cooperSignature)
End Using
Call Process.Start(New ProcessStartInfo("SignedDocument.pdf") With {.UseShellExecute = True})
End Sub
End Class
End Namespace