Technischer Artikel

AES-256-PDF-Verschlüsselung in Delphi: HotPDF-Konfiguration und Fallstricke

Im Support-Ticket stand: „Kontoauszüge öffnen sich auf unseren Desktops problemlos, aber das Records-Management-System des Kunden markiert jede Datei als unlesbar.“ Die PDFs waren mit AES-256 verschlüsselt, exakt wie im Vertrag gefordert. Die Ursache steckte in einem einzigen Boolean: Die Dokumente wurden mit Verschlüsselungsrevision 6 geschrieben, der PDF-2.0-Variante aus ISO 32000-2, während die Archiv-Toolchain des Kunden nur Revision 5 verstand. Gleicher Algorithmus, gleiche Schlüssellänge, gleiche Passwörter, aber ein anderer Key-Derivation-Handshake und ein harter Fehler, der auf keiner Entwicklungsmaschine mit aktuellem Acrobat sichtbar wurde.

Verschlüsselung ist eines der wenigen PDF-Features, bei denen eine falsche Konfiguration lokal kein sichtbares Symptom erzeugt und remote vollständig scheitert. HotPDF, eine native VCL-PDF-Komponente für Delphi und C++Builder, stellt das vollständige ISO-32000-Schutzmodell über einige wenige Eigenschaften bereit; dieser Artikel ordnet jede Eigenschaft der Entscheidung zu, die sie tatsächlich steuert.

Was die zwei Passwörter wirklich zusichern

PDF-Verschlüsselung definiert zwei Zugangsdaten mit unterschiedlichen Aufgaben, und sie zu vermischen ist der häufigste Entwurfsfehler in Code für geschützte Ausgabe. Das User-Passwort sperrt die Entschlüsselung: Ohne dieses Passwort oder das Owner-Passwort kann ein konformer Reader den Dateischlüssel nicht rekonstruieren, und der Inhalt bleibt kryptografisch unlesbar. Das Owner-Passwort sperrt die Berechtigungseinstellungen: Ein Reader, der es erhält, gewährt Vollzugriff unabhängig von Restriktionsflags.

Die Berechtigungen selbst, Drucken, Inhaltsextraktion und Ausfüllen von Formularen, sind ein schwächeres Versprechen. Sie sind Flags, die ein Viewer liest und zu beachten bereit ist (ISO 32000-2 §7.6.4). Die Verschlüsselung schützt die Bytes; die Berechtigungsflags instruieren lediglich konforme Software. Ein Benutzer, der ein Dokument legitim mit dem User-Passwort öffnet, hat den entschlüsselten Inhalt im Speicher. „Nicht kopieren“ und „nicht drucken“ sind deshalb Richtliniensignale an gut erzogene Viewer, keine kryptografischen Garantien. Modellieren Sie die Bedrohung entlang dieser Trennung: Vertraulichkeit kommt vom User-Passwort, während Berechtigungsflags das Verhalten gängiger Viewer formen und nicht mehr.

Konfigurationsreihenfolge: alles vor BeginDoc

HotPDF legt das Verschlüsselungs-Dictionary und den Dateischlüssel an, wenn BeginDoc läuft. Jede Schutzeigenschaft muss daher vorher gesetzt werden, vor allem CryptKeyLength, das über die THPDFKeyType-Werte k40, k128, aes128 und aes256 das Verfahren auswählt. Wird die Eigenschaft nach BeginDoc gesetzt, gibt es keine Exception; das Dokument behält schlicht die Parameter, mit denen es begonnen hat. Genau diese stille Abweichung taucht Monate später als Compliance-Befund wieder auf.

var
  Pdf: THotPDF;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.FileName := 'statement.pdf';
    Pdf.ActivateProtection := True;
    Pdf.CryptKeyLength := aes256;        // must be set before BeginDoc
    Pdf.UserPassword := 'open-secret';
    Pdf.OwnerPassword := 'admin-secret';
    Pdf.UseAES256R6 := False;            // R=5: widest viewer support
    Pdf.BeginDoc;
    Pdf.CurrentPage.SetFont('Arial', [], 11);
    Pdf.CurrentPage.TextOut(50, 720, 0, 'Account statement, June 2026');
    Pdf.EndDoc;
  finally
    Pdf.Free;
  end;
end;

Passwörter sind UTF-8 und auf 127 Bytes begrenzt, entsprechend der ISO-32000-2-Grenze für AES-256-Verfahren. Wenn Ihre Passwortrichtlinie längere Geheimnisse erzeugt, schneiden Sie bewusst auf Ihrer Seite ab, statt Bibliothek und zukünftigen Viewer darüber uneinig werden zu lassen, wo die Grenze liegt.

Revision 5 oder Revision 6: ein Boolean, zwei Ökosysteme

UseAES256R6 wählt zwischen zwei AES-256-Handshakes. Mit False schreibt HotPDF Revision 5, das als Erweiterung zu PDF 1.7 eingeführte AES-256-Verfahren, das von ungefähr fünfzehn Jahren Viewer-Releases unterstützt wird. Mit True schreibt es Revision 6, den gehärteten Key-Derivation-Algorithmus, der in ISO 32000-2 für PDF 2.0 standardisiert wurde und die bekannte Schwäche im Passwortprüfschritt von Revision 5 schließt.

Der technische Tausch ist Kompatibilität gegen Standardisierung. Revision 6 verlangt Viewer, die für PDF 1.7 Extension Level 3 oder PDF 2.0 gebaut sind; ältere Archivsysteme, eingebettete Renderer und nicht gewartete Fachanwendungen öffnen die Datei gar nicht, genau wie im Ticket zu Beginn dieses Artikels. Wenn eine Sicherheitsrichtlinie ISO 32000-2 Revision 6 nicht ausdrücklich nennt, liefern Sie Revision 5 aus und dokumentieren Sie die Entscheidung. Das ist die robustere Voreinstellung, und Sie können sie neu bewerten, wenn der langsamste Verbraucher aktualisiert wurde.

Dieselbe Begründung gilt eine Ebene tiefer. THPDFKeyType bietet weiterhin k40, k128 und aes128 für Kompatibilität mit älteren Toolchains, aber alle drei gehören in Wartungsarbeiten an Legacy-Systemen, nicht in neue Entwürfe: 40-Bit-RC4 ist mit Standardhardware brechbar, und die 128-Bit-Verfahren liegen vor den AES-256-Revisionen, die heutige Security Reviews erwarten. Für jedes 2026 erzeugte Dokument ist der realistische Entscheidungsraum AES-256 Revision 5 gegenüber Revision 6. Die älteren Schlüsseltypen existieren, damit Sie historische Archive reproduzieren können, nicht damit Sie neue schreiben.

Berechtigungsflags ohne Öffnungspasswort

Eine häufige Anforderung ist das Gegenteil von Geheimhaltung: Jeder darf das Dokument lesen, aber Drucken oder Extraktion sollen eingeschränkt sein. Die Konfiguration ist ein leeres User-Passwort plus ein nicht leeres Owner-Passwort, also Open-Password-Modus, mit den erlaubten Operationen in ProtectOptions.

Pdf.ActivateProtection := True;
Pdf.CryptKeyLength := aes256;
Pdf.UserPassword := '';                      // anyone can open the file
Pdf.OwnerPassword := 'rotate-me-quarterly';  // guards the permission set
Pdf.ProtectOptions := [prPrint, prPrint12bit, prExtractContent];
Pdf.BeginDoc;
// ... page content ...
Pdf.EndDoc;

Die Menge THPDFProtectOptions deckt die ISO-Berechtigungsbits ab: prPrint, prPrint12bit für hochauflösendes Drucken, prInformationCopy für allgemeines Kopieren und Extrahieren, prExtractContent für Extraktion durch assistive Technologien, prModifyStructure, prEditAnnotations, prFillAnnotations und prAssemble. Zwei davon verdienen konkrete Hinweise. Lassen Sie prExtractContent in fast jedem Profil aktiviert. Es ist das Bit, das Screenreadern und anderen assistiven Technologien Zugriff auf den Inhalt gibt, und es zu entziehen macht aus einer Rechteentscheidung einen Barrierefreiheitsfehler. Beachten Sie außerdem, dass prPrint ohne prPrint12bit in einigen Viewern zu herabgesetzter Druckqualität führt, was Endanwender eher als Renderingfehler denn als Berechtigung melden.

Die Prüfung ist schnell und sollte in Release-Checks automatisiert werden: Öffnen Sie ein Beispiel jeder Profilausgabe in Acrobat und lesen Sie den Security-Tab der Dokumenteigenschaften, der den Algorithmus („AES 256-bit“) benennt und die erlaubten Operationen einzeln auflistet. Wiederholen Sie das Öffnen anschließend im ältesten Viewer, den Ihre Kunden tatsächlich einsetzen. Die fünf Minuten für diese zweite Prüfung sind genau die Lücke, durch die das Revision-6-Ticket am Anfang dieses Artikels in Produktion gelangte.

Schutz aus vorhandenen Dateien entfernen

Entschlüsselung ist dasselbe Eigenschaftsmodell in umgekehrter Richtung: Dokument mit Zugangsdaten laden, Schutz abschalten, Ergebnis speichern.

var
  Pdf: THotPDF;
  PageCount: Integer;
begin
  Pdf := THotPDF.Create(nil);
  try
    PageCount := Pdf.LoadFromFile('encrypted.pdf', 'open-secret');
    if PageCount > 0 then
    begin
      Pdf.ActivateProtection := False;   // drop encryption on save
      Pdf.SaveLoadedDocument('plain.pdf');
    end;
  finally
    Pdf.Free;
  end;
end;

Dieser Weg parst das vollständige Dokument, was für gewöhnliche Dateien in Ordnung ist. Für Eingaben mit mehreren hundert Megabyte gibt es einen günstigeren Pfad: DecryptFile entschlüsselt während einer Kopie auf Dateiebene und nutzt einen direkten AES-256-Rewrite-Pfad, der den Aufbau des Objektbaums vermeidet, soweit die Eingabe das zulässt. Diese Funktion gehört zur Direct File API, die der Begleitartikel über die Verarbeitung großer PDFs aus Delphi beschreibt.

Einschränkungen, die mit Verschlüsselung zusammenwirken

Archivprofile stehen in direktem Konflikt: ISO 19005 verbietet Verschlüsselung in PDF/A-Dateien. Ein Workflow, der ein Dokument verschlüsselt und zugleich PDF/A-Konformität beansprucht, ist daher von vornherein ungültig. Wenn beide Anforderungen bestehen, liefern Sie zwei Artefakte aus, eine verschlüsselte Verteilungskopie und eine unverschlüsselte Archivkopie, statt beides in einer Datei erzwingen zu wollen.

Außerdem gibt es keinen Wiederherstellungspfad. PDF-Verschlüsselung hat keinen Escrow-Mechanismus: Ein verlorenes User-Passwort bei einer R5- oder R6-Datei bedeutet Brute Force oder nichts. Behandeln Sie Owner- und User-Geheimnisse wie Produktionszugangsdaten, also generiert, in einem Vault abgelegt und rotiert, niemals als Konstanten in einer Unit, wo sie in der Versionsverwaltung und in jeder Entwicklerarbeitskopie landen.

FAQ: PDFs aus Delphi schützen

Verhindert das Deaktivieren von prInformationCopy, dass Benutzer Text kopieren?

Es verhindert, dass konforme Viewer Kopierbefehle anbieten. Jeder, der das Dokument öffnen kann, hält den Klartext bereits im Speicher. Behandeln Sie das Flag daher als Workflow-Hinweis, nicht als Data-Loss-Prevention.

Sollte ein neues Projekt UseAES256R6 aktivieren?

Nur wenn verifiziert ist, dass jeder Verbraucher PDF-2.0-Verschlüsselung verarbeitet. Revision 5 bietet dieselbe AES-256-Inhaltsverschlüsselung mit deutlich breiterer Viewer-Abdeckung, weshalb sie die Voreinstellung ist.

Kann ich Berechtigungen an einem PDF ändern, das ich nicht erstellt habe?

Ja, laden Sie es mit seinem Passwort über LoadFromFile, passen Sie ProtectOptions oder die Passwörter an und schreiben Sie das Ergebnis mit SaveLoadedDocument, genau wie im obigen Entschlüsselungsbeispiel.

Die hier gezeigten Schutzeigenschaften gehören zur Standard-API von HotPDF Component für Delphi und C++Builder; die Produktseite enthält die vollständige Verschlüsselungsreferenz einschließlich der kompletten Berechtigungs-Enumeration.