Skip to content

Encrypt and decrypt PDFs in C# and .NET

Since 1.0View as Markdown

Open password protected PDFs, protect your own output with AES, and remove protection when you hold the owner password.

Call doc.Security.Encrypt with a user password, an owner password and the permissions, then save. The file is written with AES-256 unless you ask for AES-128. Open a protected file by passing the password to PdfDocument.Open.

PdfDocument doc = PdfDocument.Open("report.pdf");
doc.Security.Encrypt(
userPassword: "read", // asked for to open the file; "" lets anyone open it
ownerPassword: "admin", // unlocks every permission
permissions: PdfPermissions.Print | PdfPermissions.CopyContent); // AES-256 by default
doc.Save("report-protected.pdf");
Terminal window
dotnet add package PdfNetStack

The command line equivalents are pdfnetstack encrypt and pdfnetstack decrypt, see Command line.

PasswordWho uses itWhat it allows
User passwordAnyone who should read the file. Empty means anyone can open itViewing, plus the permissions you grant
Owner passwordYouEvery permission, and changing or removing the protection. An empty owner password is replaced by a random one

PdfPermissions flags say what a reader with only the user password may do. Combine them with |.

FlagAllows
PrintPrinting, possibly at reduced quality
PrintHighQualityPrinting at full quality
CopyContentCopying or extracting text and graphics
ExtractForAccessibilityExtracting text and graphics for accessibility
ModifyChanging content other than annotations and forms
AnnotateAdding or changing annotations and filling forms
FillFormsFilling existing form fields
AssembleInserting, rotating or deleting pages and creating bookmarks
None, AllNothing beyond viewing, or every permission (the default)

Viewers enforce permissions. They are a statement of intent to conforming software, not a technical barrier for someone who holds the file.

PdfEncryption.Aes256 (revision 6) is the default. It needs a reader that supports PDF 2.0 or PDF 1.7 extension level 8, which the file announces. PdfEncryption.Aes128 (revision 4) is readable by PDF 1.6 and later:

PdfDocument legacy = PdfDocument.Open("report.pdf");
legacy.Security.Encrypt("read", "admin", PdfPermissions.Print, PdfEncryption.Aes128); // PDF 1.6 readers
legacy.Save("report-aes128.pdf");

Pass either password. Without a password, opening tries the empty user password. A password that opens nothing raises PdfPasswordException.

PdfDocument asUser = PdfDocument.Open("report-protected.pdf", password: "read");
Console.WriteLine($"User: owner access {asUser.Security.HasOwnerAccess}, may print {asUser.Security.Permissions.HasFlag(PdfPermissions.Print)}");
try
{
PdfDocument.Open("report-protected.pdf", password: "wrong");
}
catch (PdfPasswordException ex)
{
Console.WriteLine(ex.Message);
}

doc.Security tells you what you opened:

PropertyMeaning
WasEncryptedThe file was encrypted when it was opened
HasOwnerAccessOpened with the owner password, or not encrypted
PermissionsWhat the user password grants. All for files that are not encrypted
WillEncryptSaving will write an encrypted file

Opening supports every standard security handler revision: RC4 from 40 to 128 bit, AES-128 and AES-256 (revisions 2 to 6), user and owner passwords, crypt filters and unencrypted metadata.

A document opened with its owner password keeps its encryption on save, so both passwords and the permissions still apply to the new file. RemoveEncryption saves it without protection, and Encrypt replaces the protection with new passwords.

PdfDocument opened = PdfDocument.Open("report-protected.pdf", password: "admin");
Console.WriteLine($"Owner: was encrypted {opened.Security.WasEncrypted}, will encrypt {opened.Security.WillEncrypt}");
opened.Pages.RemoveAt(0);
opened.Save("report-trimmed.pdf"); // keeps both passwords and the permissions
opened.Security.RemoveEncryption();
opened.Save("report-unprotected.pdf"); // or writes it without protection

Encryption is the last step of a save: the finished, optimized and verified file is written once more with every string and stream encrypted.

  • New protection is AES-256 or AES-128. RC4 is read but never written.
  • A document opened with only the user password can be read but not saved, and its pages can be imported into another document only when its permissions allow copying.
  • Only the standard password security handler is supported. A file protected by another handler, such as certificate based security, raises NotSupportedException when opened.
  • The optimizer returns encrypted files unchanged. Open the document with its owner password and save it to get an optimized, still encrypted file.

Questions

Which encryption does PdfNetStack write?
AES-256 (security handler revision 6) by default, or AES-128 (revision 4) for older readers. RC4 files can be opened but RC4 is never written.
Can I open a PDF with only the user password and save it again?
No. With only the user password a document can be read but not saved. Open it with the owner password to change or save it.
Does saving a protected document keep its passwords?
Yes. A document opened with its owner password is saved with its original encryption, so both passwords keep working, unless you call Encrypt or RemoveEncryption.