How-to guides/Digital Signatures

Add a digital signature to a PDF in Rust

Sign a PDF with a PKCS#12 certificate. PDFluent writes a conforming ISO 32000 signature that Adobe Acrobat, Preview, and other viewers can verify.

rust
use pdfluent::{PdfDocument, Pkcs12Signer, SignOptions};

fn main() -> pdfluent::Result<()> {
    let mut doc = PdfDocument::open("contract.pdf")?;
    let signer = Pkcs12Signer::from_pfx_file("cert.p12", "pfx-password")?;
    doc.sign(&signer, SignOptions::new().reason("Approved"))?;
    doc.save("signed.pdf")?;
    Ok(())
}

Step by step

1

Add PDFluent to your project

Add the pdfluent crate to Cargo.toml.

rust
[dependencies]
pdfluent = "1.0.0-beta.8"
2

Load your PKCS#12 certificate

Read the .p12 or .pfx certificate file and create a PdfSigner. The certificate must include the private key.

rust
use pdfluent::Pkcs12Signer;

let signer = Pkcs12Signer::from_pfx_file("my_cert.p12", "your_p12_password")?;
3

Configure signature metadata

Set the reason, location, and contact info. These appear in the signature panel in PDF viewers.

rust
use pdfluent::SignOptions;

let opts = SignOptions::new()
    .reason("I approve the content of this document")
    .location("Amsterdam, NL")
    .contact_info("[email protected]")
    .field_name("Signature1");
4

Position the visible signature appearance

Add a visible signature box on a specific page and position. Skip this step for invisible signatures.

rust
use pdfluent::SignOptions;

// Place a visible signature rectangle on page 0: [x1, y1, x2, y2] in points
let opts = SignOptions::new()
    .reason("Approved")
    .visible_rect(0, [350.0, 50.0, 550.0, 110.0]);
5

Sign the document and save

Call sign() then save(). The output file contains the cryptographic signature bytes embedded in the PDF structure.

rust
doc.sign(&signer, opts)?;
doc.save("contract_signed.pdf")?;

println!("Signed.");

Notes and tips

  • PDF signing is incremental: the original bytes are not modified, the signature is appended. This preserves prior signatures.
  • For LTV (Long-Term Validation), call opts.embed_ocsp(true) to include the OCSP response in the signature.
  • Self-signed certificates will produce a warning in Acrobat. Use a certificate from a trusted CA for production use.
  • The signature field name must be unique in the document. Signing a field that already exists replaces the signature.

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