Docs: Digital signatures
Download PDF

Digital signatures

Sign the PDF with a certificate (a .pfx file or one from the certificate store). Adobe Reader then shows who signed it and whether the file was changed afterwards.

var cert = X509CertificateLoader.LoadPkcs12FromFile("signer.pfx", "pfx-password");
var options = new PdfOptions
{
    Signature = new PdfSignatureOptions(cert)
    {
        Reason = "Approved",
        Location = "Copenhagen",
        // Optional: a visible box (points from the top-left corner; Page = -1 is the last page).
        Appearance = new PdfSignatureAppearance { Page = -1, X = 340, Y = 720, Width = 220, Height = 70 },
        // Optional: a trusted RFC 3161 timestamp (PAdES B-T). The only option that uses the network.
        TimestampUrl = "http://timestamp.digicert.com",
    },
};

// Or sign any existing PDF; earlier signatures stay valid.
byte[] signed = PdfSigner.Sign(File.ReadAllBytes("in.pdf"), new PdfSignatureOptions(cert));

// A contract template with empty signature fields: sign into one by name, at its place on the page.
byte[] countersigned = PdfSigner.Sign(contract, new PdfSignatureOptions(cert) { FieldName = "Buyer" });

Signing into an existing field

When FieldName names an empty signature field the PDF already has ("Parties.Buyer" for a nested one), the signature goes into it and the box fills the field's rectangle; signing a field of another type or one that is already signed throws PdfSignatureException. Any other name adds a new field.

Formats and compatibility

Signatures are PAdES baseline (ETSI.CAdES.detached) by default, or classic adbe.pkcs7.detached with Format = PdfSignatureFormat.Pkcs7Detached; RSA and ECDSA keys with SHA-256/384/512. The signature is appended as an incremental update, and it works together with Security (encrypted files) and Conformance (PDF/A: the visible box is drawn as outlines, so it needs no unembedded font). The CMS structure is built with .NET's own System.Formats.Asn1 and System.Security.Cryptography; no extra package is needed. Signing adds a few milliseconds (the RSA or ECDSA operation and re-reading the file); conversions without a signature are unaffected.

Edit this page on GitHub