Encryption · Python
Encrypt a PDF in Python
pip install rustpdf and AES-256-encrypt a PDF from a FastAPI route or Celery task, with V5/R6 keys from the OS CSPRNG, user and owner passwords, no qpdf binary. rust-pdf applies standard-handler encryption at output, deriving keys and IVs from the operating system CSPRNG, and supports user and owner passwords plus permission flags.
Last updated: 2026-06-29
Why Python needs this
Most Python stacks shell out to an external qpdf binary to add AES-256, which means an extra apt-get layer in every python:3.12-slim image. rust-pdf ships the cipher inside the wheel, so a slim or distroless container encrypts with zero system packages. The one caveat is Alpine, where you install the musl wheel rather than the manylinux glibc build.
Encryption runs entirely in-process: EditableDoc.load_file and ed.encrypt(...) execute on the calling thread, so you can wrap them in a FastAPI dependency, a Celery task or a Django management command without spawning a subprocess. A missing or expired Encryption license surfaces as a PdfError you can catch and turn into a 402 response or a retry.
AES-256 uses the V5/R6 security handler with keys, salts and IVs drawn from the operating-system CSPRNG, so every statement, payslip or contract you protect is byte-unique and recoverable only with the password. Set a user password to gate opening, an owner password to lock printing and copying, or both, and qpdf validates each combination.
- AES-256 (V5/R6) with keys and IVs from the OS CSPRNG, plus AES-128 and RC4 for legacy needs.
- Separate user and owner passwords, with a read-only permission mode.
- Encrypt new documents or an existing PDF you load and re-save.
Encrypt a PDF in Python with rust-pdf
Install with pip, then call the same idiomatic API every rust-pdf binding shares. The snippet below is real Python code from the reference docs.
pip install rustpdf
from rustpdf import EditableDoc, Encryption
with EditableDoc.load_file("in.pdf") as ed:
ed.encrypt(user="", owner="owner-secret",
method=Encryption.AES256, read_only=True)
ed.save("secured.pdf") # raises PdfError without an Encryption license
Python basic generation is free. Encryption is a corporate feature, unlocked by one offline license token. See pricing & licensing.
Full Python reference in the documentation.
Encryption in Python: FAQ
How strong is the encryption?
rust-pdf uses AES-256 with the modern V5/R6 security handler, the strongest standard PDF encryption. Keys, salts and IVs come from the operating system CSPRNG, so every encrypted file is unique. qpdf validates the output for both user and owner passwords.
What is the difference between user and owner passwords?
A user password is required to open the document. An owner password leaves the file openable but restricts actions such as printing or copying. You can set either or both, and enable a read-only permission mode.
Do I need a license to encrypt in Python?
Encryption is a corporate feature and needs an active license token. Basic generation in Python is free. The same offline token enables encryption in every language.
Can I encrypt inside an async FastAPI route or a Celery task?
Yes. The native call is synchronous and each EditableDoc owns its own handle, so concurrent Celery workers or threads encrypt independently with no shared state across the FFI boundary. Inside an async route, run ed.encrypt in a threadpool (await run_in_threadpool(...)) so the AES work does not hold the event loop while the document is sealed.
Start encrypting PDFs in Python
One Rust core, the same output across every language. Prototype for free, license the corporate features when you ship.