Technical Article

Criptarea PDF de mare viteză cu AES-256 pentru documente masive

În sectoarele juridic, financiar și de asistență medicală, generarea unor volume mari de documente PDF este o practică standard. Cu toate acestea, producerea documentelor este doar jumătate din bătălie; securizarea lor este la fel de critică. Când aveți un pipeline de arhivare care procesează zilnic sute de gigabytes de PDF-uri, aplicarea criptării AES-256 poate deveni rapid un blocaj de performanță.

În acest articol, vom explora cum să obținem criptare PDF AES-256 de mare viteză în Delphi evitând epuizarea memoriei și optimizând buclele criptografice.

Specificația de criptare PDF

Securitatea PDF a evoluat semnificativ. Versiunile anterioare utilizau RC4 pe 40 de biți, care astăzi poate fi spart trivial. Standardul actual (PDF 1.7 Extension Level 3 și PDF 2.0) impune criptarea AES-256.

Într-un PDF, nu criptați întregul bloc de fișier. Structura documentului (tabelul XRef și structura dicționarelor) rămâne în text simplu (plaintext). În schimb, criptați Fluxurile (datele brute pentru imagini și conținutul paginii) și Șirurile (cum ar fi textul metadatelor). Acest lucru necesită ca parserul să extragă datele, să aplice AES CBC (Cipher Block Chaining) și să le scrie la loc.

Blocajul: Încărcarea în memorie

O greșeală frecventă la criptarea unui PDF masiv (de exemplu, o arhivă scanată de 2GB) este încărcarea întregului flux într-un `TMemoryStream` înainte de a-l transmite motorului criptografic. Acest lucru duce la excepții de tip Out-Of-Memory (OOM) în procesele pe 32 de biți și la paginare (page faulting) masivă în procesele pe 64 de biți.

Criptarea în flux (streaming) în Delphi

Soluția este utilizarea unei abordări de streaming, pe bucăți (chunked). Utilizând Windows Cryptography API: Next Generation (CNG) sau o bibliotecă precum OpenSSL, puteți citi fluxul PDF în blocuri de 64KB, puteți cripta blocul și îl puteți scrie direct în fluxul de disc de ieșire.

Iată un exemplu Delphi conceptual care demonstrează o buclă de criptare cu buffer pentru un flux:

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;

Optimizarea backend-ului criptografic

Dezvoltatorii Delphi au mai multe opțiuni pentru backend-ul AES:

  • Implementări native Delphi: Ușor de implementat, dar adesea mai lente, deoarece se execută pur în software.
  • Windows CNG (BCrypt): Foarte optimizat și poate utiliza accelerarea hardware (instrucțiuni AES-NI pe procesoarele moderne Intel/AMD).
  • OpenSSL (libcrypto): Standardul din industrie, incredibil de rapid, dar necesită livrarea de fișiere DLL externe.

Pentru aplicațiile server cu debit mare, AES-NI accelerat hardware este obligatoriu. Atunci când utilizați Windows CNG în Delphi, maparea funcției BCryptEncrypt permite aplicației dumneavoastră să descarce munca grea pe siliciul criptografic dedicat al procesorului, reducând efectiv la zero overhead-ul de criptare.

Concluzie

Când criptați PDF-uri la scară de gigabytes, bazați-vă pe fragmentarea fluxului, mai degrabă decât pe stocarea completă în memorie (buffering complet), și asigurați-vă că backend-ul criptografic utilizează accelerarea hardware AES-NI. Această combinație garantează că pipeline-ul dumneavoastră de arhivare rulează la viteza unităților NVMe, în loc să fie limitat de CPU.

Notă: Criptarea AES-256 de mare viteză utilizând streaming pe fragmente este suportată nativ în HotPDF VCL Component.