Technical Article

Höghastighets AES-256 PDF-kryptering för massiva dokument

Inom juridiska, finansiella och hälsovårdssektorer är generering av stora volymer PDF-dokument standardpraxis. Att producera dokumenten är dock bara halva striden; att säkra dem är lika kritiskt. När du har en arkiveringspipeline som bearbetar hundratals gigabyte PDF-filer dagligen kan tillämpningen av AES-256-kryptering snabbt bli en prestandaflaskhals.

I den här artikeln kommer vi att utforska hur man uppnår höghastighets AES-256 PDF-kryptering i Delphi genom att undvika minnesutmattning och optimera de kryptografiska looparna.

PDF-krypteringsspecifikationen

PDF-säkerhet har utvecklats avsevärt. Tidiga versioner använde 40-bitars RC4, vilket är trivialt att knäcka idag. Den nuvarande standarden (PDF 1.7 Extension Level 3 och PDF 2.0) kräver AES-256-kryptering.

I en PDF krypterar du inte hela filblocket. Dokumentstrukturen (XRef-tabellen och strukturen för ordböcker) förblir i klartext. Istället krypterar du strömmar (rådata för bilder och sidinnehåll) och strängar (t.ex. metadatatext). Detta kräver att tolkaren extraherar datan, tillämpar AES CBC (Cipher Block Chaining) och skriver tillbaka den.

Flaskhalsen: Inläsning till minnet

Ett vanligt misstag när man krypterar en massiv PDF (t.ex. ett skannat arkiv på 2 GB) är att läsa in hela strömmen i en TMemoryStream innan den skickas till den kryptografiska motorn. Detta leder till Out-Of-Memory-undantag (OOM) i 32-bitarsprocesser och massiva sidfel (page faulting) i 64-bitarsprocesser.

Strömmande kryptering i Delphi

Lösningen är att använda en uppdelad (chunked), strömmande metod. Med hjälp av Windows Cryptography API: Next Generation (CNG) eller ett bibliotek som OpenSSL kan du läsa PDF-strömmen i block på 64 KB, kryptera blocket och skriva det direkt till utdataströmmen på disken.

Här är ett konceptuellt Delphi-exempel som demonstrerar en buffrad krypteringsloop för en ström:

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;

Optimera den kryptografiska backend-motorn

Delphi-utvecklare har flera val för AES backend-motorn:

  • Inbyggda Delphi-implementeringar: Enkla att distribuera, men ofta långsammare eftersom de enbart körs i mjukvara.
  • Windows CNG (BCrypt): Mycket optimerad och kan utnyttja hårdvaruacceleration (AES-NI-instruktioner på moderna Intel/AMD-processorer).
  • OpenSSL (libcrypto): Branschstandarden, otroligt snabb, men kräver distribution av externa DLL-filer.

För serverapplikationer med hög genomströmning är hårdvaruaccelererad AES-NI obligatoriskt. Vid användning av Windows CNG i Delphi tillåter mappning av funktionen BCryptEncrypt din applikation att flytta det tunga arbetet till processorns dedikerade kryptografiska kisel, vilket i praktiken minskar krypteringskostnaden (overhead) till nära noll.

Slutsats

När du krypterar PDF-filer i gigabyte-skala ska du förlita dig på strömuppdelning i stället för fullständig minnesbuffring, och se till att din kryptografiska backend utnyttjar hårdvaruacceleration med AES-NI. Denna kombination garanterar att din arkiveringspipeline körs i hastigheten hos dina NVMe-enheter, i stället för att vara CPU-bunden.

Obs: Höghastighets AES-256-kryptering med hjälp av uppdelad strömning stöds inbyggt i HotPDF VCL Component.