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");
Conformance validated by: qpdf

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.

Encrypt PDF files in your language

One Rust core, AES-256 encryption across eight languages: Python, C#/.NET, Go, Node.js, PHP, Ruby, Delphi, and Swift. Prototype for free, license the corporate features when you ship.

Encrypt a PDF in your language: Go, PHP, Ruby, Node.js, Python, C#.