Signing PDF Documents with a Certificate from a Windows Certificate Store


Requirements: SecureBlackbox or Secure PDF

Introduction

When looking to sign PDF documents, the signing certificate that you intend to use may be located in a Windows certificate store instead of a PFX file on disk or an HSM. For example, your certificate may have been imported into a current user (HKEY_CURRENT_USER) store, which is accessible only to a certain user account, or a local machine (HKEY_LOCAL_MACHINE) store, which is available all across the system. Certificates in both types of stores are accessed through the CryptoAPI interface and typically have private keys that are not exportable. Luckily, accessing and signing with such certificates are fully supported in the appropriate components:

This article provides guidance on configuring these components to access Windows system certificates and sign PDF documents with them.

SecureBlackbox

First, use the following CertificateStorage code to extract the certificates from the Windows store through the CryptoAPI interface:

CertificateStorage storage = new CertificateStorage(); // Opening the current user MY store storage.Open("system://currentuser@localhost/?store=MY"); Certificate signingCert = null; // Iterating through the certificates for (int i = 0; i < storage.Certificates.Count; i++) { Certificate cert = storage.Certificates[i]; Console.WriteLine("Certificate " + (i + 1).ToString() + ": " + cert.SubjectRDN); // Saving the first certificate with a private key if (cert.PrivateKeyExists) { signingCert = cert; break; } }

To access the certificates stored in the Windows store, you need to open it by providing the system URI as a parameter to the Open method. This URI includes the store type (e.g., currentuser) and the specific store to open (e.g., MY). If the specified store is opened successfully, the Certificates collection will be populated with the certificates from the store.

Once the desired certificate has been saved, you are ready to sign using PDFSigner:

PDFSigner signer = new PDFSigner(); signer.InputFile = "sample.pdf"; signer.OutputFile = "signed.pdf"; signer.SigningCertificate = signingCert; signer.Sign(); // Closing the storage storage.Close(false);

Secure PDF

With CertMgr, an event-based approach is used to list the certificates in the Windows store instead of iterating through a collection. When the ListStoreCertificates method is called, the CertList event will fire for each certificate in the store. Once you have identified the certificate, it is recommended to save it from within this event (e.g., by its subject) so that you can provide it to PDFSign in the next step.

CertMgr mgr = new CertMgr(); // Opening the current user MY store mgr.CertStoreType = CertStoreTypes.cstUser; mgr.CertStore = "MY"; string certSubject = ""; bool found = false; mgr.OnCertList += (s, e) => { // Saving the first certificate with a private key if (!found && e.HasPrivateKey) { certSubject = e.CertSubject; found = true; } }; mgr.ListStoreCertificates();

Using the saved certificate subject, assign a new Certificate object to the SigningCert property, and then sign:

PDFSign signer = new PDFSign(); signer.InputFile = "sample.pdf"; signer.OutputFile = "signed.pdf"; signer.SigningCert = new Certificate(CertStoreTypes.cstUser, "MY", "password", certSubject); signer.Sign();

We appreciate your feedback. If you have any questions, comments, or suggestions about this article please contact our support team at support@nsoftware.com.