Encryption
Protect PDFs with AES-256 encryption, control what users can do with permission flags, open and decrypt password-protected files, and remove restrictions from locked documents.
Encrypting a Document
Use Encrypt with an Encryption256Bit object to apply AES-256 encryption (the recommended standard for all new content):
PdfEditor.Open("report.pdf")
.Encrypt(new Encryption256Bit
{
OwnerPassword = "admin-2026",
UserPassword = "reader-2026"
})
.Save("report-encrypted.pdf");
Encrypt a Generated Document
Use PdfEditor.Create to generate and encrypt in a single chain:
PdfEditor.Create(doc =>
{
doc.Page(page =>
{
page.Size(PageSizes.A4);
page.Margin(50);
page.Content().Column(col =>
{
col.Item().Text("Confidential Financial Data").FontSize(20).Bold();
col.Item().PaddingTop(20).Text("Revenue: $4,821,000");
col.Item().Text("Net Income: $1,203,000");
});
});
})
.SetTitle("Q1 Financial Summary")
.Encrypt(new Encryption256Bit
{
OwnerPassword = "finance-admin",
UserPassword = "finance-reader",
AllowPrinting = false,
AllowContentExtraction = false
})
.Save("q1-financials.pdf");
Owner Password vs User Password
| Password | Purpose | Required? |
|---|---|---|
| OwnerPassword | Full access: can remove encryption, change permissions, and edit the document. This is the "master key". | Yes — qpdf requires it. |
| UserPassword | Needed to open the document. When empty or null, anyone can open the file, but the document is still encrypted and respects permission restrictions. | No — defaults to empty string. |
Owner-only encryption. It is common to set only the OwnerPassword and leave UserPassword empty. This lets anyone open the PDF but prevents unauthorized users from lifting restrictions (e.g. printing or copying text) without knowing the owner password.
Owner-Only Encryption (No Open Password)
PdfEditor.Open("manual.pdf")
.Encrypt(new Encryption256Bit
{
OwnerPassword = "master-key-2026",
// UserPassword is null — anyone can open
AllowPrinting = true,
AllowContentExtraction = false,
AllowAnnotation = false
})
.Save("manual-protected.pdf");
Permission Flags
Permission flags control what operations are allowed when the document is opened with the user password. The owner password always grants full access regardless of these flags.
Encryption256Bit Properties
| Property | Type | Default | Description |
|---|---|---|---|
OwnerPassword | string | "" | Master password. Required — must not be empty at save time. |
UserPassword | string? | null | Password to open the document. Null or empty = no open password. |
AllowPrinting | bool | true | Permits printing the document. |
AllowContentExtraction | bool | true | Permits copying text and images from the document. |
AllowAnnotation | bool | true | Permits adding or modifying annotations and form fields. |
AllowAssembly | bool | true | Permits page assembly (insert, delete, rotate pages, add bookmarks). |
AllowFillingForms | bool | true | Permits filling in form fields (even when annotation is disabled). |
EncryptMetadata | bool | true | Encrypts the XMP metadata stream. Set to false if metadata should remain searchable in cleartext. |
Common Permission Combinations
| Use Case | Printing | Extract | Annotate | Assembly | Forms |
|---|---|---|---|---|---|
| Read-only (maximum restriction) | false | false | false | false | false |
| Print-only (no copy/paste) | true | false | false | false | false |
| Fill forms only | false | false | false | false | true |
| Full access (encryption only) | true | true | true | true | true |
Read-Only Document
PdfEditor.Open("contract.pdf")
.Encrypt(new Encryption256Bit
{
OwnerPassword = "legal-admin",
UserPassword = "view-only",
AllowPrinting = false,
AllowContentExtraction = false,
AllowAnnotation = false,
AllowAssembly = false,
AllowFillingForms = false
})
.Save("contract-locked.pdf");
Fillable Form with Printing
PdfEditor.Open("application-form.pdf")
.Encrypt(new Encryption256Bit
{
OwnerPassword = "hr-admin-2026",
AllowPrinting = true,
AllowFillingForms = true,
AllowContentExtraction = false,
AllowAnnotation = false,
AllowAssembly = false
})
.Save("application-form-protected.pdf");
Encryption Levels
FolioPDF supports three encryption levels. Use 256-bit AES for all new content unless you must support very old PDF readers:
| Class | Algorithm | PDF Version | Recommendation |
|---|---|---|---|
Encryption256Bit | AES-256 | PDF 2.0 / 1.7 ext 3 | Recommended for all new content. |
Encryption128Bit | AES-128 / RC4-128 | PDF 1.4 – 1.6 | Use only when targeting Acrobat 7–9 era tools. |
Encryption40Bit | RC4-40 | PDF 1.1 | Legacy only. Trivially crackable. Avoid. |
128-Bit Encryption
PdfEditor.Open("document.pdf")
.Encrypt(new Encryption128Bit
{
OwnerPassword = "admin",
UserPassword = "reader",
AllowPrinting = true,
AllowContentExtraction = true
})
.Save("document-128bit.pdf");
40-Bit Encryption (Legacy)
PdfEditor.Open("legacy-document.pdf")
.Encrypt(new Encryption40Bit
{
OwnerPassword = "admin",
AllowPrinting = true,
AllowContentExtraction = true,
AllowModification = true,
AllowAnnotation = true
})
.Save("legacy-encrypted.pdf");
40-bit RC4 is not secure. The 40-bit key space can be brute-forced in minutes on modern hardware. It exists in FolioPDF solely for backward compatibility with PDF 1.1 tools (pre-2001). Never use it for actual security.
Opening Encrypted Files
Pass the password to PdfEditor.Open to edit an encrypted document:
PdfEditor.Open("encrypted-report.pdf", password: "reader-2026")
.SetTitle("Updated Title")
.Save("encrypted-report-updated.pdf");
Opening from Bytes
byte[] encryptedBytes = File.ReadAllBytes("encrypted.pdf");
PdfEditor.Open(encryptedBytes, password: "my-secret")
.AddBookmark("Summary", pageIndex: 0)
.Save("encrypted-bookmarked.pdf");
Inspecting Encrypted Files
The PdfiumDocument inspection API also accepts a password:
using var doc = PdfiumDocument.Load(
File.ReadAllBytes("protected.pdf"),
password: "reader-password");
Console.WriteLine($"Pages: {doc.PageCount}");
Console.WriteLine($"Title: {doc.GetMetadata().Title}");
using var page = doc.GetPage(0);
string text = page.ExtractText();
Console.WriteLine($"First page text: {text[..100]}...");
Decrypting a Document
Remove all encryption from a document (you need the owner or user password to open it first):
PdfEditor.Open("encrypted-report.pdf", password: "admin-2026")
.Decrypt()
.Save("report-decrypted.pdf");
The output file has no encryption at all — no passwords, no restrictions.
Removing Restrictions
RemoveRestrictions() strips all security restrictions and decrypts the document. This is the "unlock everything" operation:
PdfEditor.Open("locked.pdf", password: "admin-password")
.RemoveRestrictions()
.Save("unlocked.pdf");
Digital signatures. Removing restrictions invalidates any digital signatures on the document. If the document was signed, the signature verification will fail after this operation.
Re-Encrypting with Different Settings
Open an encrypted file, decrypt it, then re-encrypt with different passwords or permissions:
PdfEditor.Open("old-encrypted.pdf", password: "old-admin")
.Decrypt()
.Encrypt(new Encryption256Bit
{
OwnerPassword = "new-admin-2026",
UserPassword = "new-reader-2026",
AllowPrinting = true,
AllowContentExtraction = false
})
.Save("re-encrypted.pdf");
Encryption with Linearization
Encryption and linearization can be combined. qpdf handles the correct internal ordering:
PdfEditor.Open("report.pdf")
.SetTitle("Quarterly Report")
.Encrypt(new Encryption256Bit
{
OwnerPassword = "admin-key",
AllowPrinting = true,
AllowContentExtraction = false
})
.Linearize()
.Save("report-secure-web.pdf");
XMP Metadata Encryption
By default, EncryptMetadata is true — the XMP metadata stream is encrypted along with the rest of the document. Set it to false if you need document metadata to remain searchable in cleartext (e.g. for document management systems that index encrypted PDFs):
PdfEditor.Open("report.pdf")
.Encrypt(new Encryption256Bit
{
OwnerPassword = "secure-key",
EncryptMetadata = false // metadata stays in cleartext
})
.Save("report-searchable-metadata.pdf");
Security Best Practices
| Practice | Rationale |
|---|---|
Always use Encryption256Bit for new content | AES-256 is the only level that provides meaningful cryptographic security. 40-bit and 128-bit are legacy. |
| Use strong, unique owner passwords | The owner password is the master key. A weak owner password undermines all permission restrictions. |
| Consider omitting the user password | If anyone should be able to open the document but not modify it, leave UserPassword empty and rely on permission flags. |
Set AllowContentExtraction = false for confidential documents | Prevents casual copy/paste of text and images. Note: determined users can always screenshot the content. |
| Combine encryption with redaction for sensitive data | Encryption protects the file. Redaction permanently removes content (SSNs, financial data). Use both for defence in depth. |
| Store passwords securely | Never hard-code passwords in source code. Use secret managers, environment variables, or configuration providers. |
| Test with Acrobat and Chrome | Verify that permissions are enforced correctly in the viewers your users will use. Different viewers enforce restrictions with varying strictness. |
PDF encryption is DRM, not impenetrable security. PDF permission flags are enforced by the viewer application, not by cryptography. A compliant viewer will respect them, but open-source tools can often bypass restrictions. For truly sensitive data, combine encryption with redaction to permanently remove content that should never be exposed, and consider additional controls at the infrastructure level (access control, audit logging).
Complete Example: Secure Document Pipeline
PdfEditor.Create(doc =>
{
doc.Page(page =>
{
page.Size(PageSizes.A4);
page.Margin(50);
page.Content().Column(col =>
{
col.Item().Text("Merger & Acquisition Proposal").FontSize(24).Bold();
col.Item().PaddingTop(15).Text(
"This document contains material non-public information. " +
"Distribution is restricted to authorised personnel only.");
// ... detailed content ...
});
});
})
.SetTitle("M&A Proposal - Project Phoenix")
.SetAuthor("Corporate Development")
.StampText(new TextStamp("CONFIDENTIAL")
{
FontSize = 60, Opacity = 0.12f, Rotation = -45,
Color = Color.FromHex("#CC0000"), Bold = true
})
.Encrypt(new Encryption256Bit
{
OwnerPassword = Environment.GetEnvironmentVariable("PDF_OWNER_KEY")!,
UserPassword = "phoenix-2026",
AllowPrinting = false,
AllowContentExtraction = false,
AllowAnnotation = false,
AllowAssembly = false,
AllowFillingForms = false
})
.Save("proposal-phoenix-secure.pdf");
Next Steps
- Digital Signing — PFX/X509 signatures and verification
- Compression — reduce file size before encrypting
- Metadata & Bookmarks — document properties and navigation