Technical Article

Visokohitrostno šifriranje AES-256 PDF datotek za masivne dokumente

V pravnem, finančnem in zdravstvenem sektorju je ustvarjanje velikih količin PDF dokumentov standardna praksa. Vendar pa je izdelava dokumentov le polovica bitke; njihovo varovanje je enako kritično. Kadar imate arhivski cevovod, ki dnevno obdela na stotine gigabajtov PDF datotek, lahko uporaba šifriranja AES-256 hitro postane ozko grlo v zmogljivosti.

V tem članku bomo raziskali, kako doseči visokohitrostno šifriranje AES-256 PDF dokumentov v Delphiju z izogibanjem izčrpanosti pomnilnika in optimizacijo kriptografskih zank.

Specifikacija šifriranja PDF

Varnost datotek PDF se je znatno razvila. Zgodnje različice so uporabljale 40-bitni RC4, ki je danes enostavno zlomljiv. Trenutni standard (PDF 1.7 Extension Level 3 in PDF 2.0) zahteva šifriranje AES-256.

V PDF-ju ne šifrirate celotnega bloka datoteke. Struktura dokumenta (tabela XRef in struktura slovarjev) ostane nešifrirana. Namesto tega šifrirate tokove (Streams) (neobdelane podatke za slike in vsebino strani) ter nize (Strings) (kot je besedilo metapodatkov). To zahteva od razčlenjevalnika, da izlušči podatke, uporabi AES CBC (Cipher Block Chaining) in jih zapiše nazaj.

Ozko grlo: Nalaganje v pomnilnik

Pogosta napaka pri šifriranju masivnega PDF dokumenta (npr. 2 GB skeniranega arhiva) je nalaganje celotnega toka v `TMemoryStream`, preden ga posredujete kriptografskemu mehanizmu. To vodi do izjem Out-Of-Memory (OOM) v 32-bitnih procesih in do masivnih napak strani (page faulting) v 64-bitnih procesih.

Pretočno šifriranje (Streaming Encryption) v Delphiju

Rešitev je uporaba pretočnega pristopa v kosih (chunked, streaming). Z uporabo API-ja Windows Cryptography: Next Generation (CNG) ali knjižnice, kot je OpenSSL, lahko tok PDF preberete v 64 KB velikih blokih, blok šifrirate in ga zapišete neposredno v izhodni tok diska.

Tukaj je konceptualni primer v Delphiju, ki prikazuje zanko šifriranja z medpomnilnikom (buffered) za tok:

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;

Optimizacija kriptografskega zaledja

Razvijalci v Delphiju imajo za zaledje AES na voljo več izbir:

  • Izvorne (native) Delphi implementacije: Enostavne za uvajanje, vendar pogosto počasnejše, saj se izvajajo izključno v programski opremi.
  • Windows CNG (BCrypt): Visoko optimizirano in lahko uporablja strojno pospeševanje (inštrukcije AES-NI na sodobnih procesorjih Intel/AMD).
  • OpenSSL (libcrypto): Industrijski standard, neverjetno hiter, vendar zahteva distribucijo zunanjih knjižnic DLL.

Za strežniške aplikacije z visoko prepustnostjo je strojno pospešen AES-NI obvezen. Pri uporabi Windows CNG v Delphiju vam preslikava funkcije BCryptEncrypt omogoča, da težko delo prenesete na namenski kriptografski silicij procesorja, s čimer se režija šifriranja učinkovito zmanjša na skoraj nič.

Zaključek

Pri šifriranju gigabajtnih PDF datotek se zanesite na ločevanje tokov (chunking) namesto na polno pomnilniško medpomnjenje in zagotovite, da vaše kriptografsko zaledje izkorišča strojno pospeševanje AES-NI. Ta kombinacija zagotavlja, da vaš arhivski cevovod deluje s hitrostjo vaših diskov NVMe, namesto da bi bil omejen s procesorjem (CPU-bound).

Opomba: Visokohitrostno šifriranje AES-256, ki uporablja razčlenjeno pretakanje, je izvorno podprto v komponenti HotPDF VCL Component.