Skip to content

PDFs in Python, Rust, Go verschlüsseln und entschlüsseln

Abdeckung der Bindings. Die Entschlüsselung (Öffnen mit Passwort) ist in allen fünf Bindings verfügbar. Das Speichern neu verschlüsselter PDFs steht in Python, Rust, Go (DocumentEditor.SaveEncrypted) und WASM (saveEncryptedToBytes) zur Verfügung. Die öffentliche C#-API bietet über PdfDocument.OpenWithPassword das passwortgeschützte Öffnen, ein öffentlicher SaveEncrypted-Wrapper ist jedoch noch nicht freigegeben — nutzen Sie die Rust-CLI oder die Go-/Python-Bindings, wenn Sie aus einer C#-Pipeline verschlüsselte PDFs erzeugen möchten.

Ein PDF mit Passwort verschlüsseln:

Python

from pdf_oxide import PdfDocument

doc = PdfDocument("report.pdf")
doc.save_encrypted("protected.pdf", "userpass", "ownerpass")

WASM

import { WasmPdfDocument } from "pdf-oxide-wasm";

const doc = new WasmPdfDocument(bytes);
const encrypted = doc.saveEncryptedToBytes("userpass", "ownerpass", true, true, true, true);
// encrypted is a Uint8Array
doc.free();

Rust

use pdf_oxide::api::Pdf;

let mut doc = Pdf::open("report.pdf")?;
doc.save_encrypted("protected.pdf", "userpass", "ownerpass")?;

Go

package main

import (
    "log"
    pdfoxide "github.com/yfedoseev/pdf_oxide/go"
)

func main() {
    editor, err := pdfoxide.OpenEditor("report.pdf")
    if err != nil { log.Fatal(err) }
    defer editor.Close()

    if err := editor.SaveEncrypted("protected.pdf", "userpass", "ownerpass"); err != nil {
        log.Fatal(err)
    }
}

C++

#include <pdf_oxide/pdf_oxide.hpp>

auto editor = pdf_oxide::DocumentEditor::open("report.pdf");
editor.save_encrypted("protected.pdf", "userpass", "ownerpass");

Swift

import PdfOxide

let editor = try DocumentEditor.open("report.pdf")
try editor.saveEncrypted("protected.pdf", userPassword: "userpass", ownerPassword: "ownerpass")

Dart

import 'package:pdf_oxide/pdf_oxide.dart';

final editor = DocumentEditor.open('report.pdf');
editor.saveEncrypted('protected.pdf', 'userpass', 'ownerpass');
editor.close();

R

library(pdfoxide)

editor <- pdf_editor_open("report.pdf")
pdf_editor_save_encrypted(editor, "protected.pdf", "userpass", "ownerpass")
pdf_editor_close(editor)

Julia

using PdfOxide

editor = open_editor("report.pdf")
save_encrypted(editor, "protected.pdf", "userpass", "ownerpass")

Zig

const pdf_oxide = @import("pdf_oxide");

var editor = try pdf_oxide.DocumentEditor.open("report.pdf");
defer editor.deinit();
try editor.saveEncrypted("protected.pdf", "userpass", "ownerpass");

Objective-C

#import "POXPdfOxide.h"
NSError *err = nil;

POXDocumentEditor *editor = [POXDocumentEditor openEditor:@"report.pdf" error:&err];
[editor saveEncryptedToPath:@"protected.pdf"
               userPassword:@"userpass"
              ownerPassword:@"ownerpass"
                      error:&err];

Elixir

{:ok, editor} = PdfOxide.open_editor("report.pdf")
:ok = PdfOxide.editor_save_encrypted(editor, "protected.pdf", "userpass", "ownerpass")

Ein verschlüsseltes PDF öffnen:

Python

from pdf_oxide import PdfDocument

doc = PdfDocument("protected.pdf", password="userpass")
text = doc.extract_text(0)
print(text)

WASM

const doc = new WasmPdfDocument(encryptedBytes);
doc.authenticate("userpass");
const text = doc.extractText(0);
console.log(text);
doc.free();

Rust

let mut doc = Pdf::open_with_password("protected.pdf", "userpass")?;
let text = doc.extract_text(0)?;
println!("{}", text);

Go

doc, _ := pdfoxide.Open("protected.pdf")
defer doc.Close()

if _, err := doc.Authenticate("userpass"); err != nil { log.Fatal(err) }
text, _ := doc.ExtractText(0)
fmt.Println(text)

C#

using PdfOxide;

using var doc = PdfDocument.OpenWithPassword("protected.pdf", "userpass");
Console.WriteLine(doc.ExtractText(0));

C++

auto doc = pdf_oxide::Document::open_with_password("protected.pdf", "userpass");
auto text = doc.extract_text(0);
std::cout << text << "\n";

Swift

let doc = try Document.openWithPassword("protected.pdf", password: "userpass")
let text = try doc.extractText(0)
print(text)

Dart

final doc = PdfDocument.openWithPassword('protected.pdf', 'userpass');
final text = doc.extractText(0);
print(text);

R

doc <- pdf_open_with_password("protected.pdf", "userpass")
text <- pdf_extract_text(doc, 0)
cat(text)

Julia

doc = open_with_password("protected.pdf", "userpass")
text = extract_text(doc, 0)
println(text)

Zig

var doc = try pdf_oxide.Document.openWithPassword("protected.pdf", "userpass");
defer doc.deinit();
const text = try doc.extractText(a, 0);
defer a.free(text);

Objective-C

POXDocument *doc = [POXDocument openWithPassword:@"protected.pdf" password:@"userpass" error:&err];
NSString *text = [doc extractText:0 error:&err];
NSLog(@"%@", text);

Elixir

{:ok, doc} = PdfOxide.open_with_password("protected.pdf", "userpass")
{:ok, text} = PdfOxide.extract_text(doc, 0)
IO.puts(text)

PDF Oxide verwendet standardmäßig AES-256-Verschlüsselung. MIT-lizenziert, keine AGPL-Einschränkungen.

Installation

pip install pdf_oxide

PDFs verschlüsseln

Grundlegende Verschlüsselung

Python

from pdf_oxide import PdfDocument

doc = PdfDocument("input.pdf")
doc.save_encrypted("output.pdf", "user123", "owner456")

WASM

const doc = new WasmPdfDocument(bytes);
const encrypted = doc.saveEncryptedToBytes("user123", "owner456", true, true, true, true);
doc.free();

Rust

let mut doc = Pdf::open("input.pdf")?;
doc.save_encrypted("output.pdf", "user123", "owner456")?;

C++

auto editor = pdf_oxide::DocumentEditor::open("input.pdf");
editor.save_encrypted("output.pdf", "user123", "owner456");

Swift

let editor = try DocumentEditor.open("input.pdf")
try editor.saveEncrypted("output.pdf", userPassword: "user123", ownerPassword: "owner456")

Dart

final editor = DocumentEditor.open('input.pdf');
editor.saveEncrypted('output.pdf', 'user123', 'owner456');
editor.close();

R

editor <- pdf_editor_open("input.pdf")
pdf_editor_save_encrypted(editor, "output.pdf", "user123", "owner456")
pdf_editor_close(editor)

Julia

editor = open_editor("input.pdf")
save_encrypted(editor, "output.pdf", "user123", "owner456")

Zig

var editor = try pdf_oxide.DocumentEditor.open("input.pdf");
defer editor.deinit();
try editor.saveEncrypted("output.pdf", "user123", "owner456");

Objective-C

POXDocumentEditor *editor = [POXDocumentEditor openEditor:@"input.pdf" error:&err];
[editor saveEncryptedToPath:@"output.pdf"
               userPassword:@"user123"
              ownerPassword:@"owner456"
                      error:&err];

Elixir

{:ok, editor} = PdfOxide.open_editor("input.pdf")
:ok = PdfOxide.editor_save_encrypted(editor, "output.pdf", "user123", "owner456")
  • Benutzerpasswort — zum Öffnen und Anzeigen des Dokuments erforderlich
  • Eigentümerpasswort — für den Vollzugriff erforderlich (Drucken, Kopieren, Bearbeiten)

Nur Öffnungspasswort

Benutzerpasswort setzen, aber keine Berechtigungen einschränken:

doc = PdfDocument("input.pdf")
doc.save_encrypted("locked.pdf", "viewpass", "adminpass")

Kein Öffnungspasswort, aber Aktionen einschränken

Jedem das Anzeigen erlauben, aber Drucken und Kopieren unterbinden:

Python

doc = PdfDocument("input.pdf")
doc.save_encrypted(
    "restricted.pdf",
    "",            # No password to open
    "adminpass",   # Owner password for full access
    allow_print=False,
    allow_copy=False,
    allow_modify=False,
    allow_annotate=False,
)

WASM

const doc = new WasmPdfDocument(bytes);
const restricted = doc.saveEncryptedToBytes(
    "",           // No password to open
    "adminpass",  // Owner password for full access
    false,        // allowPrint
    false,        // allowCopy
    false,        // allowModify
    false         // allowAnnotate
);
doc.free();

Rust

let config = EncryptionConfig::new("", "adminpass")
    .with_permissions(Permissions::none());
doc.save_with_encryption("restricted.pdf", config)?;

Nur Drucken erlauben

Anzeigen und Drucken erlauben, Kopieren und Bearbeiten aber sperren:

Python

doc = PdfDocument("input.pdf")
doc.save_encrypted(
    "print-only.pdf",
    "",
    "adminpass",
    allow_print=True,
    allow_copy=False,
    allow_modify=False,
)

WASM

const doc = new WasmPdfDocument(bytes);
const printOnly = doc.saveEncryptedToBytes(
    "",           // No password to open
    "adminpass",
    true,         // allowPrint
    false,        // allowCopy
    false,        // allowModify
    true          // allowAnnotate
);
doc.free();

Rust

let config = EncryptionConfig::new("", "adminpass")
    .with_permissions(Permissions::print_only());
doc.save_with_encryption("print-only.pdf", config)?;

Berechtigungsoptionen

Parameter Standard Beschreibung
allow_print True Drucken des Dokuments erlauben
allow_copy True Kopieren von Text und Grafiken erlauben
allow_modify True Inhalte ändern erlauben
allow_annotate True Anmerkungen hinzufügen erlauben

PDFs entschlüsseln

Mit Passwort öffnen

Python

from pdf_oxide import PdfDocument

doc = PdfDocument("encrypted.pdf", password="secret")
text = doc.extract_text(0)
print(f"Pages: {doc.page_count()}")

WASM

const doc = new WasmPdfDocument(encryptedBytes);
doc.authenticate("secret");
const text = doc.extractText(0);
console.log(`Pages: ${doc.pageCount()}`);
doc.free();

Rust

let mut doc = Pdf::open_with_password("encrypted.pdf", "secret")?;
let text = doc.extract_text(0)?;
println!("Pages: {}", doc.page_count()?);

C++

auto doc = pdf_oxide::Document::open_with_password("encrypted.pdf", "secret");
auto text = doc.extract_text(0);
std::cout << "Pages: " << doc.page_count() << "\n";

Swift

let doc = try Document.openWithPassword("encrypted.pdf", password: "secret")
let text = try doc.extractText(0)
print("Pages: \(try doc.pageCount())")

Dart

final doc = PdfDocument.openWithPassword('encrypted.pdf', 'secret');
final text = doc.extractText(0);
print('Pages: ${doc.pageCount}');

R

doc <- pdf_open_with_password("encrypted.pdf", "secret")
text <- pdf_extract_text(doc, 0)
cat("Pages:", pdf_page_count(doc), "\n")

Julia

doc = open_with_password("encrypted.pdf", "secret")
text = extract_text(doc, 0)
println("Pages: ", page_count(doc))

Zig

var doc = try pdf_oxide.Document.openWithPassword("encrypted.pdf", "secret");
defer doc.deinit();
const text = try doc.extractText(a, 0);
defer a.free(text);
std.debug.print("Pages: {d}\n", .{try doc.pageCount()});

Objective-C

POXDocument *doc = [POXDocument openWithPassword:@"encrypted.pdf" password:@"secret" error:&err];
NSString *text = [doc extractText:0 error:&err];
NSLog(@"Pages: %ld", (long)[doc pageCountError:&err]);

Elixir

{:ok, doc} = PdfOxide.open_with_password("encrypted.pdf", "secret")
{:ok, text} = PdfOxide.extract_text(doc, 0)
{:ok, pages} = PdfOxide.page_count(doc)
IO.puts("Pages: #{pages}")

Ohne Verschlüsselung speichern

Ein verschlüsseltes PDF öffnen und eine unverschlüsselte Kopie ablegen:

Python

from pdf_oxide import PdfDocument

doc = PdfDocument("encrypted.pdf", password="secret")
doc.save("decrypted.pdf")

WASM

const doc = new WasmPdfDocument(encryptedBytes);
doc.authenticate("secret");
const decrypted = doc.save();
// decrypted is an unencrypted Uint8Array
doc.free();

Rust

let mut doc = Pdf::open_with_password("encrypted.pdf", "secret")?;
doc.save("decrypted.pdf")?;

Mit einem anderen Passwort neu verschlüsseln

Python

from pdf_oxide import PdfDocument

doc = PdfDocument("old-protected.pdf", password="oldpass")
doc.save_encrypted("new-protected.pdf", "newuser", "newowner")

WASM

const doc = new WasmPdfDocument(encryptedBytes);
doc.authenticate("oldpass");
const reEncrypted = doc.saveEncryptedToBytes("newuser", "newowner", true, true, true, true);
doc.free();

Rust

let mut doc = Pdf::open_with_password("old-protected.pdf", "oldpass")?;
doc.save_encrypted("new-protected.pdf", "newuser", "newowner")?;

Stapelverschlüsselung

Alle PDFs in einem Verzeichnis verschlüsseln:

from pdf_oxide import PdfDocument, PdfError
from pathlib import Path

input_dir = Path("reports/")
output_dir = Path("protected/")
output_dir.mkdir(exist_ok=True)

for pdf_path in input_dir.glob("*.pdf"):
    try:
        doc = PdfDocument(str(pdf_path))
        out_path = output_dir / pdf_path.name
        doc.save_encrypted(
            str(out_path),
            "company2025",
            "admin2025",
            allow_print=True,
            allow_copy=False,
        )
        print(f"Encrypted: {pdf_path.name}")
    except PdfError as e:
        print(f"Failed: {pdf_path.name}: {e}")

Stapelentschlüsselung

Alle PDFs mit einem bekannten Passwort entschlüsseln:

from pdf_oxide import PdfDocument, PdfError
from pathlib import Path

input_dir = Path("protected/")
output_dir = Path("decrypted/")
output_dir.mkdir(exist_ok=True)

for pdf_path in input_dir.glob("*.pdf"):
    try:
        doc = PdfDocument(str(pdf_path), password="company2025")
        out_path = output_dir / pdf_path.name
        doc.save(str(out_path))
        print(f"Decrypted: {pdf_path.name}")
    except PdfError as e:
        print(f"Failed: {pdf_path.name}: {e}")

Unterstützte Algorithmen

PDF Oxide unterstützt alle gängigen PDF-Verschlüsselungsalgorithmen:

Algorithmus Schlüssellänge Sicherheit
AES-256 256 Bit Am stärksten (Standard)
AES-128 128 Bit Stark
RC4-128 128 Bit Veraltet
RC4-40 40 Bit Schwach (nur zur Kompatibilität)

save_encrypted() nutzt standardmäßig AES-256. Wenn Sie den Algorithmus explizit wählen möchten, verwenden Sie die Rust-API mit EncryptionConfig.

Warum nicht pdfplumber oder pdfminer?

Weder pdfplumber noch pdfminer kommen mit verschlüsselten PDFs zurecht:

  • pdfplumber — bricht bei passwortgeschützten PDFs mit einem Fehler ab. Keine Entschlüsselung.
  • pdfminer — nur eingeschränkte Unterstützung; scheitert an AES-256-verschlüsselten Dateien.
  • pypdf — entschlüsselt zwar, ist bei der Textextraktion nach der Entschlüsselung jedoch 15× langsamer als PDF Oxide.

Wenn Sie verschlüsselte PDFs in großem Umfang verarbeiten müssen, erledigt PDF Oxide sowohl die Entschlüsselung als auch die Verschlüsselung nativ mit AES-128 und AES-256.

Verwandte Seiten