Technical Article

Vysokorychlostní šifrování AES-256 pro masivní PDF dokumenty

V právním, finančním a zdravotnickém sektoru je generování velkých objemů PDF dokumentů běžnou praxí. Vytvoření dokumentů je však jen polovina bitvy, jejich zabezpečení je stejně tak kritické. Pokud máte archivační systém, který denně zpracovává stovky gigabajtů PDF souborů, může se použití šifrování AES-256 rychle stát úzkým hrdlem z hlediska výkonu.

V tomto článku prozkoumáme, jak dosáhnout vysokorychlostního šifrování PDF pomocí AES-256 v Delphi, a to tím, že se vyhneme vyčerpání paměti a optimalizujeme kryptografické cykly.

Specifikace šifrování PDF

Zabezpečení PDF se významně vyvinulo. Rané verze používaly 40bitový algoritmus RC4, který je dnes snadno prolomitelný. Současný standard (PDF 1.7 Extension Level 3 a PDF 2.0) vyžaduje šifrování AES-256.

V PDF nešifrujete celý blok souboru. Struktura dokumentu (tabulka XRef a struktura slovníků) zůstává ve formátu prostého textu. Místo toho šifrujete Streamy (nezpracovaná data pro obrázky a obsah stránek) a Řetězce (například text metadat). To vyžaduje, aby analyzátor extrahoval data, aplikoval AES CBC (Cipher Block Chaining) a zapsal je zpět.

Úzké hrdlo: Načítání do paměti

Častou chybou při šifrování masivního PDF (např. 2GB naskenovaného archivu) je načtení celého streamu do `TMemoryStream` před jeho předáním kryptografickému modulu. To vede k výjimkám typu nedostatek paměti (OOM) ve 32bitových procesech a masivním výpadkům stránek (page faulting) v 64bitových procesech.

Šifrování streamů v Delphi

Řešením je použít po částech (chunked) streamovací přístup. Pomocí rozhraní Windows Cryptography API: Next Generation (CNG) nebo knihovny, jako je OpenSSL, můžete číst PDF stream v 64KB blocích, blok zašifrovat a zapsat jej přímo do výstupního diskového streamu.

Zde je koncepční příklad v Delphi, který demonstruje šifrovací smyčku s vyrovnávací pamětí pro stream:

uses
  System.Classes, System.SysUtils;

const
  BUFFER_SIZE = 65536; // 64KB chunks

// This represents your AES-256 encryption routine
procedure EncryptStreamChunk(const InBuffer; var OutBuffer; BytesRead: Integer; const Key: TBytes; const IV: TBytes);
begin
  // Call to Windows CNG (BCryptEncrypt) or OpenSSL (EVP_EncryptUpdate)
  // ...
end;

procedure EncryptLargePDFStream(InputStream, OutputStream: TStream; const Key, IV: TBytes);
var
  InBuffer, OutBuffer: array of Byte;
  BytesRead: Integer;
begin
  SetLength(InBuffer, BUFFER_SIZE);
  // AES CBC requires padding, so the output buffer must be slightly larger
  SetLength(OutBuffer, BUFFER_SIZE + 16); 

  InputStream.Position := 0;
  OutputStream.Position := 0;

  repeat
    BytesRead := InputStream.Read(InBuffer[0], BUFFER_SIZE);
    if BytesRead > 0 then
    begin
      EncryptStreamChunk(InBuffer[0], OutBuffer[0], BytesRead, Key, IV);
      // Write the encrypted cipher text directly to disk
      OutputStream.Write(OutBuffer[0], BytesRead); // Note: padding logic omitted for brevity
    end;
  until BytesRead < BUFFER_SIZE;
end;

Optimalizace kryptografického backendu

Vývojáři v Delphi mají několik možností pro backend AES:

  • Nativní implementace Delphi: Snadné nasazení, ale často pomalejší, protože se spouštějí čistě softwarově.
  • Windows CNG (BCrypt): Vysoce optimalizované a může využívat hardwarovou akceleraci (instrukce AES-NI na moderních procesorech Intel/AMD).
  • OpenSSL (libcrypto): Průmyslový standard, neuvěřitelně rychlý, ale vyžaduje dodání externích DLL knihoven.

Pro serverové aplikace s vysokou propustností je hardwarově akcelerovaný AES-NI povinností. Při použití Windows CNG v Delphi umožňuje mapování funkce BCryptEncrypt vaší aplikaci přenést náročné operace na vyhrazený kryptografický čip procesoru, čímž se režie šifrování efektivně snižuje téměř na nulu.

Závěr

Při šifrování PDF souborů o velikosti gigabajtů se spoléhejte spíše na rozdělování streamu na části než na ukládání do vyrovnávací paměti jako celku a zajistěte, aby váš kryptografický backend využíval hardwarovou akceleraci AES-NI. Tato kombinace zaručuje, že vaše archivační linka poběží rychlostí vašich NVMe disků, namísto aby byla omezována výkonem procesoru.

Poznámka: Vysokorychlostní šifrování AES-256 s využitím chunked streamingu je nativně podporováno v komponentě HotPDF VCL Component.