How-to guides/Digital Signatures

Verify a PDF digital signature in Rust

Check that a PDF signature is cryptographically valid and that the document has not been modified since it was signed.

rust
use pdfluent::{PdfDocument, SignatureVerifier};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let doc = PdfDocument::open("contract_signed.pdf")?;
    let verifier = SignatureVerifier::new();

    for sig in doc.signatures() {
        let result = verifier.verify(&sig)?;
        println!("Signature: {}", sig.field_name());
        println!("  Integrity: {}", result.integrity_valid);
        println!("  Certificate trusted: {}", result.certificate_trusted);
        println!("  Signer: {:?}", result.signer_name);
    }
    Ok(())
}
Install:cargo add pdfluentDownload SDK →

Step by step

1

Add PDFluent to your project

Add the pdfluent crate to Cargo.toml.

rust
[dependencies]
pdfluent = "0.9"
2

Open the signed PDF

Load the document. A read-only borrow is sufficient for verification.

rust
use pdfluent::PdfDocument;

let doc = PdfDocument::open("signed_invoice.pdf")?;
3

List signatures in the document

Call doc.signatures() to get all signature fields. Each item includes the field name, signing time, and the raw certificate chain.

rust
let signatures = doc.signatures();
println!("Found {} signature(s)", signatures.len());

for sig in &signatures {
    println!("Field: {}", sig.field_name());
    println!("Signing time: {:?}", sig.signing_time());
    println!("Certificate subject: {}", sig.certificate().subject());
}
4

Verify signature integrity

SignatureVerifier checks that the signed byte range matches the current file contents. If any byte outside the signature field has changed, integrity_valid is false.

rust
use pdfluent::SignatureVerifier;

let verifier = SignatureVerifier::new();

for sig in doc.signatures() {
    let result = verifier.verify(&sig)?;

    if result.integrity_valid {
        println!("OK - document not modified since signing");
    } else {
        println!("FAIL - document was modified after signing");
    }
}
5

Verify the certificate chain

Check that the signing certificate chains to a trusted root. Supply your own trust store or use the system store.

rust
use pdfluent::{SignatureVerifier, TrustStore};

// Use system root certificates
let verifier = SignatureVerifier::with_trust_store(TrustStore::system());

for sig in doc.signatures() {
    let result = verifier.verify(&sig)?;
    println!("Trusted: {}", result.certificate_trusted);
    println!("Signer: {:?}", result.signer_name);
    println!("Valid from: {:?}", result.certificate_valid_from);
    println!("Valid until: {:?}", result.certificate_valid_until);
}

Notes and tips

  • integrity_valid checks cryptographic hash only. certificate_trusted checks the CA chain separately.
  • PDF signatures cover a specific byte range. Content added after signing (incremental updates) falls outside that range.
  • For LTV-enabled signatures, call result.ltv_valid() to check embedded OCSP and CRL data.
  • A self-signed certificate will produce certificate_trusted = false unless you add it to a custom TrustStore.

Why PDFluent for this

Pure Rust

No JVM, no runtime, no DLL dependencies. Ships as a single native binary or WASM module.

Memory safe

Rust's ownership model prevents buffer overflows and use-after-free. No segfaults in PDF parsing.

Runs anywhere

Same code runs server-side, in Docker, on AWS Lambda, on Cloudflare Workers, or in the browser via WASM.

Frequently asked questions