Guide
How to validate a signed PDF in C#
Use Pdf.GetSignaturesAsync() to enumerate signed fields, then call
ValidateIntegrityAsync() or ValidateAsync(...).
ZingPDF validates the PDF /ByteRange, reads the detached CMS payload from
/Contents, and reports integrity, coverage, certificate, revocation, timestamp, and permission
results separately.
Validate signature integrity
ValidateIntegrityAsync() checks that the signed byte ranges still match the detached CMS
signature. It does not use the machine trust store, network revocation checks, or the current clock.
using ZingPDF;
using var pdf = Pdf.Load(File.OpenRead("contract-signed.pdf"));
var signatures = await pdf.GetSignaturesAsync();
var result = await signatures[0].ValidateIntegrityAsync();
if (result.Status == PdfSignatureValidationStatus.Valid)
{
Console.WriteLine("The signed byte ranges match the CMS signature.");
}
Validate from a signature field
If your code already has the AcroForm field, call ValidateSignatureAsync(...) on the
SignatureFormField.
using ZingPDF;
using ZingPDF.Elements.Forms.FieldTypes.Signature;
using var pdf = Pdf.Load(File.OpenRead("contract-signed.pdf"));
var form = await pdf.GetFormAsync();
var field = await form!.GetFieldAsync<SignatureFormField>("Approval.Signature");
var result = await field!.ValidateSignatureAsync();
Build a certificate chain
Use ValidateAsync(...) when you want certificate-chain validation. You can pass extra
intermediate certificates or custom trusted roots through PdfSignatureValidationOptions.
using System.Security.Cryptography.X509Certificates;
using ZingPDF;
using var pdf = Pdf.Load(File.OpenRead("contract-signed.pdf"));
using var trustedRoot = new X509Certificate2("trusted-root.cer");
var signatures = await pdf.GetSignaturesAsync();
var result = await signatures[0].ValidateAsync(new PdfSignatureValidationOptions
{
Profile = PdfSignatureValidationProfile.CertificateChain,
TrustedRoots = new X509Certificate2Collection(trustedRoot)
});
Read the validation result
The top-level Status is a summary. Inspect the layer results when you need to distinguish a
changed PDF from an untrusted certificate or unsigned bytes appended after signing.
Console.WriteLine(result.Status);
Console.WriteLine(result.Integrity.Status);
Console.WriteLine(result.Coverage.HasUnsignedChangesAfterSignature);
Console.WriteLine(result.Certificate.Status);
foreach (var finding in result.Findings)
{
Console.WriteLine($"{finding.Code}: {finding.Message}");
}
Current limits
ZingPDF validates ByteRange integrity, detached CMS signatures, signer certificate extraction, and optional X509Chain validation. Trusted timestamp token validation, DSS/VRI long-term validation data, and DocMDP certification permissions are reported as separate result layers but are not validated yet.
Signature validation requires a seekable input stream because the signed byte ranges are reconstructed from the original PDF bytes.
Need to sign the PDF first?
Create a detached CMS signature in an existing field or a hidden field before validating the saved output.