Digital signatures · Node.js and TypeScript

Digitally sign a PDF in Node.js

Add a cryptographic PKCS#7 or PAdES signature to a PDF from Node.js. rust-pdf signs through a non-destructive incremental update, so the original bytes are preserved and the signature stays verifiable in Adobe Reader, pdfsig and any PAdES validator.

Last updated: 2026-06-29

Why Node.js and TypeScript needs this

Signing a PDF in Node normally pulls in a native toolkit with a build step, or pipes bytes through an external signer, which is fragile in CI and hard to run inside a request handler.

A real digital signature gives a document legal weight: it proves who signed it and that nothing changed afterwards. rust-pdf builds the detached CMS by hand to control the ByteRange, supports PAdES B-B, B-LT and B-LTA for long-term validation, and lets you supply your own key and certificate as DER.

From a Fastify or NestJS handler, read the PKCS#8 key and X.509 certificate with fs.readFileSync as Buffers, convert a PEM or PKCS#12 bundle to DER once with openssl, then call rustpdf.sign and write or return the signed Buffer. Signing is CPU-bound, so wrap it in an async job for busy endpoints; the pure-FFI Koffi binding adds no node-gyp step.

  • PKCS#7 detached and PAdES B-B, with B-LT and B-LTA for long-term validation.
  • Incremental update: the original file is preserved byte for byte, so earlier signatures stay valid.
  • Bring your own key and X.509 certificate (PKCS#8 DER), or chain to a TSA for timestamps.

Sign a PDF in Node.js with rust-pdf

Install from npm, read your DER key and certificate as Buffers, and pass them to rustpdf.sign. The snippet below is real Node.js from the reference docs and verifies with pdfsig.

npm install rustpdf

Node.js
const fs = require("fs");
const rustpdf = require("rustpdf");

const pdf     = fs.readFileSync("contract.pdf");
const keyDer  = fs.readFileSync("signing-key.pkcs8.der");   // PKCS#8 private key (DER)
const certDer = fs.readFileSync("signing-cert.der");        // X.509 certificate (DER)

const signed = rustpdf.sign(pdf, keyDer, certDer, {
  reason: "Approved", location: "New York",
  name: "Jane Doe", pades: true,
});
fs.writeFileSync("contract.signed.pdf", signed);
// Verify in a shell: pdfsig contract.signed.pdf  →  "Signature is Valid."
Validated by: pdfsigopensslqpdf

Node.js basic generation is free. Signing is a corporate feature, unlocked by one offline license token. See pricing & licensing.

The full Node.js signing reference is in the documentation.

Signing in Node.js: FAQ

Is the signature legally valid?

rust-pdf produces standards-compliant PKCS#7 and PAdES signatures. Legal validity depends on the certificate you sign with (for example an eIDAS qualified certificate or an ICP-Brasil certificate). The library handles the cryptography and the PDF structure correctly, which is what validators such as pdfsig and Adobe Reader check.

Does it support long-term validation (LTV)?

Yes. After signing you can append a Document Security Store with certificates and CRLs (PAdES B-LT) and an RFC 3161 document timestamp (PAdES B-LTA), all offline. A trusted external TSA and live OCSP fetching are the only parts that need network infrastructure.

Do I need a license to sign in Node.js?

Signing is a corporate feature, so it requires an active license token. Basic PDF generation in Node.js is free. The same offline Ed25519 token unlocks signing across every language.

What key and certificate format does the Node binding expect?

rustpdf.sign takes a PKCS#8 private key and an X.509 certificate as DER Buffers. If you hold a PEM file or a PKCS#12 (.pfx) bundle, convert it to DER once with openssl, then read both files with fs.readFileSync and pass the Buffers straight into sign.

Sign documents inline and keep the originals intact

One Rust core, the same PAdES signatures in every language. Prototype on the free tier, then unlock signing with one offline Ed25519 token when you ship.