Concept · Encryption
Password-Protect & Encrypt PDF Files
in Code, Explained
Last updated: 2026-06-29
PDF's standard security handler supports two passwords: a user password that encrypts the content so only the right recipient can open it, and an owner password that controls permissions such as printing and editing. This guide explains the difference, covers AES-256 versus AES-128 versus the legacy RC4 cipher, and shows you how to apply all of it in code. For a deep dive into the cipher itself, see What is AES-256?
The simplest analogy: a safe with two keys
Think of an encrypted PDF as a physical safe. The user key is the combination you give to whoever should open the door. Without it, the contents are sealed and unreadable. The owner key is the master key held by the administrator: it can open the safe and also change the rules inside, for example deciding that a document can be viewed but not printed or copied.
A file can carry either key, both, or neither. The important point is that only the user password triggers real encryption of the content. Setting an owner password without a user password leaves the safe unlocked for anyone; it just places an advisory sign on the door about what is allowed inside. For real confidentiality, combine a strong user password with AES-256.
User password vs owner password
PDF's standard security handler supports two distinct passwords. They do different jobs, and understanding the difference matters for security.
User password
Also called the open password. Required to open the file.
- Encrypts the content. Without the password the PDF body is ciphertext, unreadable.
- Shown to the reader as a password prompt when opening the file.
- Needed for real confidentiality. This is the key your recipient must have.
- Can be set alone, without an owner password.
Owner password
Also called the permissions password. Controls what users can do.
- Controls permission flags such as printing, copying, and editing.
- Does not encrypt the content on its own; the file is still readable without it.
- Advisory only when set without a user password. Many tools ignore the flags.
- Typically kept by the document author or administrator.
Encryption methods: RC4, AES-128, and AES-256
PDF supports three encryption methods through its standard security handler. Only AES-256 is recommended for new documents. See What is AES-256? for a detailed look at how the cipher works.
| Method | Key length | PDF revision | Status | Notes |
|---|---|---|---|---|
| RC4 | 40 or 128 bit | R2 / R3 | Avoid | Legacy stream cipher with known weaknesses. Present in older PDF readers but unsafe for new content. |
| AES-128 | 128 bit | R4 | Acceptable | Adequate for many use cases. Validated by qpdf. Supported by all modern PDF readers. |
| AES-256 | 256 bit | R6 | Recommended | Current best practice. rust-pdf uses the OS CSPRNG for IVs and file-key salts (getrandom), validated by qpdf for both user and owner passwords. |
rust-pdf implements all three: Encryption.RC4,
Encryption.AES128, and Encryption.AES256.
Key derivation and per-object encryption follow the PDF specification
exactly, then qpdf verifies the output for both passwords.
A note on permissions vs real protection
Permission flags are a courtesy signal to cooperative software, not a security boundary.
Owner-only restrictions are widely ignorable
If you set an owner password but no user password, the PDF content itself is not encrypted. Any reader, command-line tool, or script can open the file and access the full text and images, regardless of the permission flags. Tools that respect the flags do so voluntarily; many do not.
The flags (printing allowed, copying allowed, and similar) are meaningful only as a signal to cooperative software. They are not a substitute for real encryption. If your goal is to prevent someone from reading the document, you need a user password and AES-256.
rust-pdf also exposes a read_only flag (Python) or fourth
boolean parameter (Go) that sets the standard read-only permission bits
alongside the encryption, for readers that honour them.
When to encrypt a PDF
Any document that should reach only specific eyes benefits from a user password and AES-256 encryption applied before delivery.
Confidential reports
Board packs, financial results, or analyst reports that must reach only specific recipients.
HR and payroll
Pay slips, offer letters, and performance reviews delivered per-employee with individual passwords.
Medical records
Patient summaries, test results, and referrals where confidentiality is a regulatory requirement.
Read-only distribution
Published price lists, contracts, or certificates where editing should be discouraged and content protected.
Account statements
Bank statements, invoices, and billing summaries generated per-customer and encrypted before delivery.
Secure file delivery
Any automated pipeline that must ensure a document is readable only by the intended party, not by anyone who intercepts it in transit.
How to encrypt a PDF with rust-pdf
Load, set passwords and method, save. AES-256 is recommended. The same API works across all eight language bindings.
# pip install rustpdf
import rustpdf
ed = rustpdf.EditableDoc.load(open("document.pdf", "rb").read())
ed.encrypt(user="open-me", owner="full-control",
method=rustpdf.Encryption.AES256)
ed.save("encrypted.pdf")
// dotnet add package RustPdf
using RustPdf;
using var ed = EditableDoc.Load(File.ReadAllBytes("document.pdf"));
ed.Encrypt(user: "open-me", owner: "full-control", method: Encryption.Aes256);
ed.Save("encrypted.pdf");
// go get github.com/rustpdf/rustpdf-go@latest
ed, _ := rustpdf.Load(mustRead("document.pdf"))
defer ed.Close()
ed.Encrypt(rustpdf.AES256, "open-me", "full-control", false) // method, user, owner, readOnly
ed.Save("encrypted.pdf")
// npm install rustpdf
const { EditableDoc, Encryption } = require("rustpdf");
const fs = require("fs");
const ed = EditableDoc.load(fs.readFileSync("document.pdf"));
ed.encrypt({ method: Encryption.Aes256, user: "open-me", owner: "full-control" });
ed.save("encrypted.pdf");
rust-pdf derives the file key and the /O and /U
entries, encrypts every object's strings and streams, and writes the
/Encrypt dict after (the dict itself is never encrypted). For
AES-256/R6 the OS CSPRNG makes each encryption unique. Full details in the
documentation and in
What is AES-256?
PDF encryption FAQ
How do I password-protect a PDF in code?
Load the PDF as an EditableDoc, call encrypt with your chosen user and owner passwords and method AES256, then save. With rust-pdf in Python: ed = rustpdf.EditableDoc.load(data); ed.encrypt(user='open-me', owner='full-control', method=rustpdf.Encryption.AES256); ed.save('encrypted.pdf'). The same API is available in C#, Go, Node.js, PHP, Ruby, Delphi, and Swift.
What is the difference between a user and owner password?
The user password (also called the open password) is required to open and view the document. Without it, a reader cannot display the content. The owner password (also called the permissions password) controls what a user who has opened the document is allowed to do, such as printing or copying text. A document can set either password, both, or neither. Setting only an owner password does not encrypt the content, just the permission flags.
Which encryption method should I use?
Use AES-256 (R6), the current recommendation. RC4 is a legacy cipher and should be avoided for new documents. AES-128 is adequate but older. AES-256 is validated by qpdf for both user and owner passwords, uses the OS CSPRNG for unique IVs, and implements the full R6 algorithm as defined in the PDF specification. See What is AES-256? for how the cipher works.
Are owner-only permission restrictions secure?
No. If you set an owner password but no user password, the PDF content is not encrypted. Any PDF reader, tool, or script can open and read the file. The permission flags that restrict printing or copying are merely advisory and are widely ignored by tools. For real confidentiality, always set a user password combined with AES-256 encryption. That encrypts the content so it cannot be read without the password.
Is each encrypted file unique?
Yes, for AES-256 (R6). rust-pdf draws the AES initialization vectors and the file key salts from the OS CSPRNG (via getrandom), so encrypting the same document twice produces two byte-distinct outputs even with identical passwords. The output is validated by qpdf for both user and owner passwords. Note that this means encrypted documents are not byte-reproducible across runs, unlike plain documents.