Decrypt a password-protected PDF and save a clean, unencrypted copy. Requires the owner password.
use pdfluent::PdfDocument;
fn main() -> pdfluent::Result<()> {
// Open with the owner password (or user password)
let mut doc = PdfDocument::open_with_password(
"protected.pdf",
"owner-pw-123",
)?;
doc.remove_encryption()?;
doc.save("unprotected.pdf")?;
println!("Password removed. Saved unprotected.pdf.");
Ok(())
}Encryption removal is part of the encryption feature.
# Cargo.toml
[dependencies]
pdfluent = { version = "0.9", features = ["encryption"] }You need the owner password to remove encryption. The user password only grants read access. If you only have the user password, you cannot remove or modify the encryption.
use pdfluent::PdfDocument;
let mut doc = PdfDocument::open_with_password(
"protected.pdf",
"owner-pw-123",
)?;open_with_password() returns Error::WrongPassword if the password is incorrect. Handle this in a pipeline to log failures without crashing.
use pdfluent::{PdfDocument, Error};
match PdfDocument::open_with_password("protected.pdf", "owner-pw-123") {
Ok(doc) => {
println!("Opened successfully");
// ... proceed
}
Err(Error::WrongPassword) => {
eprintln!("Wrong password. Cannot remove encryption.");
}
Err(Error::PasswordRequired) => {
eprintln!("File is encrypted but no password was supplied.");
}
Err(e) => eprintln!("Error: {}", e),
}remove_encryption() strips all encryption dictionaries from the document. The saved file is a plain PDF with no password required.
doc.remove_encryption()?;
doc.save("unprotected.pdf")?;
// Verify by opening without a password
let check = PdfDocument::open("unprotected.pdf")?;
println!("Encrypted: {}", check.is_encrypted()); // falseCombine with a directory scan to decrypt a folder of PDFs at once.
use std::fs;
use pdfluent::{PdfDocument, Error};
let password = "owner-pw-123";
for entry in fs::read_dir("./encrypted")?.filter_map(|e| e.ok()) {
let path = entry.path();
if path.extension().map_or(false, |e| e == "pdf") {
match PdfDocument::open_with_password(&path, password) {
Ok(mut doc) => {
doc.remove_encryption()?;
let out = std::path::Path::new("./decrypted")
.join(path.file_name().unwrap());
doc.save(out)?;
println!("Decrypted: {}", path.display());
}
Err(Error::WrongPassword) => {
eprintln!("Wrong password: {}", path.display());
}
Err(e) => eprintln!("Error {}: {}", path.display(), e),
}
}
}No JVM, no runtime, no DLL dependencies. Ships as a single native binary or WASM module.
Rust's ownership model prevents buffer overflows and use-after-free. No segfaults in PDF parsing.
Same code runs server-side, in Docker, on AWS Lambda, on Cloudflare Workers, or in the browser via WASM.