How-to guides/Digital Signatures

Read digital signature details from a PDF in Rust

Inspect the signer certificate, signing time, and signature coverage for each digital signature in a PDF.

rust
use pdfluent::Document;

fn main() -> pdfluent::Result<()> {
    let doc = Document::open("signed.pdf")?;

    for sig in doc.signatures() {
        println!("Signer:       {}", sig.signer_name().unwrap_or("unknown"));
        println!("Signed at:    {:?}", sig.signing_time());
        println!("Covers whole: {}", sig.covers_whole_document());
        println!("Cert issuer:  {}", sig.certificate()?.issuer());
        println!("---");
    }

    Ok(())
}
Install:cargo add pdfluentDownload SDK →

Step by step

1

Open the signed PDF

doc.signatures() returns an iterator over all digital signature fields in the AcroForm.

rust
let doc = Document::open("signed.pdf")?;
2

List all signatures

Each Signature object provides access to the signer name from the certificate, signing time, and field name.

rust
for sig in doc.signatures() {
    println!("Field: {}", sig.field_name());
    println!("Signer: {}", sig.signer_name().unwrap_or("(unknown)"));
}
3

Read certificate details

sig.certificate() returns the end-entity certificate. You can inspect the subject, issuer, serial number, and validity period.

rust
let cert = sig.certificate()?;
println!("Subject:    {}", cert.subject());
println!("Issuer:     {}", cert.issuer());
println!("Serial:     {}", cert.serial_number_hex());
println!("Valid from: {:?}", cert.not_before());
println!("Valid to:   {:?}", cert.not_after());
4

Check signing time and byte range

The signing time may come from the certificate or from an embedded timestamp token. covers_whole_document checks whether the byte ranges cover the entire file.

rust
println!("Signing time: {:?}", sig.signing_time());
println!("Has timestamp token: {}", sig.has_timestamp_token());
println!("Covers whole document: {}", sig.covers_whole_document());

let (ranges_bytes, total_bytes) = sig.byte_range_coverage(&doc)?;
println!("Covered {}/{} bytes", ranges_bytes, total_bytes);
5

Check if the document has been modified after signing

If the byte ranges do not cover the entire file, content was appended after signing. This does not mean the signature is invalid, but it may indicate incremental updates.

rust
if !sig.covers_whole_document() {
    println!("Warning: document was modified after signing.");
}

Notes and tips

  • Reading signature info does not verify the cryptographic integrity. Call sig.verify() to perform a cryptographic check.
  • A PDF may contain multiple signatures, each covering different byte ranges. This is normal in multi-party signing workflows.
  • The signing time in the signature dictionary is set by the signer and can be spoofed. Use has_timestamp_token() and embedded TSA tokens for trusted time.
  • Certificate chain validation requires a trust store. Pass a custom trust store with sig.verify_with_trust_store(&store).

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