PDFOne .NET
Powerful all-in-one PDF library for .NET
Compatibility
VS 2005/2008/2010/2012/2013

How To Digitally Sign A PDF Document Using a certificate in the Windows Certificate Store In C#.NET

Using PDFOne .NET
By Santhanam L

In PDFOne .NET Version 7.6, we introduced support for digital signing using a certificate in the Windows Certificate Store. In this article, you will see how to sign PDF documents using a certificate in the Windows Certificate Store which also lists the certificates installed in the USB token when the token is connected to the system.

A USB token is a password-protected physical device used to store digital certificates. To sign PDF documents using a USB token, you need a digital signature certificate that is installed on a USB token. USB token based certificates are an implementation of PKCS#11, one of the Public-Key Cryptography Standards. Digital signature certificates are issued by a Certificate Authority (CA). When the USB token is connected to the system, the certificates in the token are added automatically to the Windows Certificate Store under the store name “My”. In order to sign the document using a certificate installed on the USB token you need to know the issuer common name & serial number of the certificate, and a valid password/PIN to access the USB token.

Identifying the issuer common name and serial number of the required certificate

You can use PDFDocument.FindCertificatesByName() method which iterates through the certificates in the specified Windows Certificate store to find the certificates that match the search criteria specified by the optional parameters of the method. As a result the method returns a list of string objects with each string object containing comma separated value of the certificate details such as issuer common name, serial number, etc. This API also includes the certificates in the USB token device when the token is connected to the system. The code example below shows you how to use PDFDocument.addSignature() method.

PDFDocument doc = new PDFDocument("LICENSE-KEY");

// The name of the Certificate Store
string certificateStoreName = "My";
// Search criteria to filter the results using issuer name of the certificate
string certificateIssuerCommonName = "GlobalSign";
/*
 * Specifies whether to filter the results using Time valid certificates 
 * according to current date and time on the computer
 */
bool findByTimeValid = true;
// Specifies whether to filter the results with only valid/verified certificates
bool includeOnlyValidCertificates = true;

ArrayList certificateNames = doc.FindCertificatesByName(certificateStoreName, 
  certificateIssuerCommonName, findByTimeValid, includeOnlyValidCertificates);

/* 
 * iterate and print the results to identify the issuer common name 
 * and serial number of the required certificate.
 */
foreach (string certificateName in certificateNames)
{
    Console.WriteLine(certificateName);
}

doc.Close();

Sample output:

CN=GlobalSign CA 2 for AATL, O=GlobalSign nv-sa, C=BE, SerialNumber=CFAE6C882722B7704F0D

Signing a PDF document using a Certificate in the Windows Certificate Store

You can load an existing document and sign straightaway using PDFDocument.AddSignature() method. PDFOne will take care of adding the signature field. The code example below shows you how to use PDFDocument.AddSignature() method.

string inputFileName = "InputDocument.pdf";
string outputFileName = "OutputDocument.pdf";

// Load an existing PDF document
PDFDocument pdfDoc = new PDFDocument("LICENSE-KEY");
pdfDoc.Load(inputFileName);

// name of the Certificate Store
string certificateStoreName = "My";
// issuer name of the certificate
string certificateIssuerCommonName = "GlobalSign";
// serial number of the certificate
string certificateSerialNumber = "CFAE6C882722B7704F0D";

/*
 * Supply the required parameters to read the certificate from the store, 
 * signature details, page number, and location.
 */
pdfDoc.AddSignature(certificateStoreName, 
  certificateIssuerCommonName, 
  certificateSerialNumber,
  "John Doe", // signer's name
  "Approving the document", // reason
  "Bangalore, India", // location
  "johndoe@email.com", // contact info
  1, // page number
  "sigFld1", // field name
  new RectangleF(0.7f, 0.7f, 1.5f, 0.7f)); // location on page

pdfDoc.Save(outputFileName);
pdfDoc.Close();

When the above program is executed, the token’s authentication client may prompt for the password/PIN to access the USB token, if the required certificate to use for signing is available in the USB token.

Once a valid password/PIN is supplied, the signing process will be completed successfully.

The following code snippets demonstrate couple of digital signing scenarios.

Scenario 1: I want to load an existing document and sign it. Then, when I view the output document in consumer applications such as Adobe Reader, I should see the validation result such as check mark over the signature field. NOTE: Usage of this feature is a violation of PAdES standard.

string inputFileName = "InputDocument.pdf";
string outputFileName = "OutputDocument.pdf";

PDFDocument pdfDoc = new PDFDocument("LICENSE-KEY");
pdfDoc.Load(inputFileName);

// name of the Certificate Store
string certificateStoreName = "My";
// issuer name of the certificate
string certificateIssuerCommonName = "GlobalSign";
// serial number of the certificate
string certificateSerialNumber = "CFAE6C882722B7704F0D";

/*
 * Supply the required parameters to read the certificate from the store, 
 * signature details, page number, and location.
 */
PDFSignature pdfSignature = new PDFSignature(certificateStoreName,
  certificateIssuerCommonName,
  certificateSerialNumber,
  "John Doe", // signer's name
  "Approving the document", // reason
  "Bangalore, India", // location
  "johndoe@email.com", // contact info
  1); // page number

PDFFormSignatureField sigFld = new PDFFormSignatureField("SigField1");
sigFld.Rectangle = new RectangleF(0.7f, 0.7f, 1.5f, 0.7f);
sigFld.Fill(pdfSignature);

// specify whether validation result appearance should be included
sigFld.IncludeValidationResultAppearance = true;

/*
 * specify if validation result appearance text should not be
 * shown when IncludeValidationResultAppearance is true.
 */
//sigFld.IncludeValidationResultAppearanceText = false;

pdfDoc.AddFormField(sigFld);

pdfDoc.Save(outputFileName);
pdfDoc.Close();

Scenario 2: I want to load a document and fill an existing blank signature form field. Also, I want to specify that the signature is detached (i.e., the original signed message digest over the document’s byte range shall be incorporated as the normal CMS SignedData field).

string inputFileName = "InputDocument.pdf";
string outputFileName = "OutputDocument.pdf";

PDFDocument pdfDoc = new PDFDocument("LICENSE-KEY");
pdfDoc.Load(inputFileName);

// name of the Certificate Store
string certificateStoreName = "My";
// issuer name of the certificate
string certificateIssuerCommonName = "GlobalSign";
// serial number of the certificate
string certificateSerialNumber = "CFAE6C882722B7704F0D";

/*
 * Supply the required parameters to read the certificate from the store, 
 * signature details, page number, and location.
 */
PDFSignature pdfSignature = new PDFSignature(certificateStoreName,
  certificateIssuerCommonName,
  certificateSerialNumber,
  "John Doe", // signer's name
  "Approving the document", // reason
  "Bangalore, India", // location
  "johndoe@email.com", // contact info
  1); // page number

// specify whether the signature is detached
pdfSignature.IsDetached = true;

// Retrieve a list of all signature fields
ArrayList fieldsList = pdfDoc.GetAllFormFields(1, PDFFormFieldType.Signature);

// Iterate the list and fill the required signature field
foreach (PDFFormSignatureField signatureField in fieldsList)
{
    if (signatureField.IsUnsigned())
    {
        signatureField.Fill(pdfSignature);
        break;
    }
}

pdfDoc.Save(outputFileName);
pdfDoc.Close();

---o0O0o---

Our .NET Developer Tools
Gnostice Document Studio .NET

Multi-format document-processing component suite for .NET developers.

PDFOne .NET

A .NET PDF component suite to create, edit, view, print, reorganize, encrypt, annotate, and bookmark PDF documents in .NET applications.

Our Delphi/C++Builder developer tools
Gnostice Document Studio Delphi

Multi-format document-processing component suite for Delphi/C++Builder developers, covering both VCL and FireMonkey platforms.

eDocEngine VCL

A Delphi/C++Builder component suite for creating documents in over 20 formats and also export reports from popular Delphi reporting tools.

PDFtoolkit VCL

A Delphi/C++Builder component suite to edit, enhance, view, print, merge, split, encrypt, annotate, and bookmark PDF documents.

Our Java developer tools
XtremeDocumentStudio (for Java)

Multi-format document-processing component suite for Java developers.

PDFOne (for Java)

A Java PDF component suite to create, edit, view, print, reorganize, encrypt, annotate, bookmark PDF documents in Java applications.

Our Platform-Agnostic Cloud and On-Premises APIs
StarDocs

Cloud-hosted and On-Premises REST-based document-processing and document-viewing APIs

Privacy | Legal | Feedback | Newsletter | Blog | Resellers © 2002-2019 Gnostice Information Technologies Private Limited. All rights reserved.