Technical Article

Høj hastighed AES-256 PDF-kryptering til massive dokumenter

Inden for juridiske, finansielle og sundhedsrelaterede sektorer er generering af store mængder PDF-dokumenter standardpraksis. At producere dokumenterne er dog kun det halve af kampen; at sikre dem er lige så kritisk. Når du har en arkiveringspipeline, der behandler hundredvis af gigabyte PDF'er dagligt, kan anvendelse af AES-256 kryptering hurtigt blive en flaskehals for ydeevnen.

I denne artikel vil vi se på, hvordan man opnår højhastigheds AES-256 PDF-kryptering i Delphi ved at undgå hukommelsesudmattelse og optimere de kryptografiske sløjfer.

PDF-krypteringsspecifikationen

PDF-sikkerhed har udviklet sig betydeligt. Tidlige versioner brugte 40-bit RC4, som er trivielt at bryde i dag. Den nuværende standard (PDF 1.7 Extension Level 3 og PDF 2.0) påkræver AES-256 kryptering.

I en PDF krypterer du ikke hele filblokken. Dokumentstrukturen (XRef-tabellen og strukturen af ordbøger) forbliver i klartekst. I stedet krypterer du Streams (de rå data til billeder og sideindhold) og Strings (såsom metadatatekst). Dette kræver, at parseren udtrækker dataene, anvender AES CBC (Cipher Block Chaining) og skriver det tilbage.

Flaskehalsen: Indlæsning til hukommelsen

En almindelig fejl ved kryptering af en massiv PDF (f.eks. et 2 GB scannet arkiv) er at indlæse hele streamen i en TMemoryStream, før den sendes til den kryptografiske motor. Dette fører til Out-Of-Memory (OOM) undtagelser i 32-bit processer og massiv sidefejl (page faulting) i 64-bit processer.

Streaming-kryptering i Delphi

Løsningen er at bruge en opdelt (chunked) streaming-tilgang. Ved hjælp af Windows Cryptography API: Next Generation (CNG) eller et bibliotek som OpenSSL kan du læse PDF-streamen i 64 KB-blokke, kryptere blokken og skrive den direkte til output-disk-streamen.

Her er et konceptuelt Delphi-eksempel, der demonstrerer en bufret krypteringssløjfe for en 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;

Optimering af den kryptografiske backend

Delphi-udviklere har flere valgmuligheder til AES-backenden:

  • Indfødte Delphi-implementeringer: Nemme at udrulle, men ofte langsommere, da de udelukkende udføres i software.
  • Windows CNG (BCrypt): Meget optimeret og kan udnytte hardwareacceleration (AES-NI instruktioner på moderne Intel/AMD CPU'er).
  • OpenSSL (libcrypto): Industristandarden, utroligt hurtig, men kræver distribution af eksterne DLL'er.

For højtydende serverapplikationer er hardwareaccelereret AES-NI obligatorisk. Ved brug af Windows CNG i Delphi tillader kortlægning af BCryptEncrypt-funktionen din applikation at overlade det tunge arbejde til CPU'ens dedikerede kryptografiske silicium, hvilket effektivt reducerer krypteringsomkostningerne til næsten nul.

Konklusion

Når du krypterer PDF'er i gigabyte-skala, skal du stole på stream-opdeling (chunking) i stedet for fuld hukommelsesbufring og sikre, at din kryptografiske backend udnytter hardware AES-NI acceleration. Denne kombination garanterer, at din arkiveringspipeline kører med samme hastighed som dine NVMe-drev, frem for at være CPU-begrænset.

Bemærk: Højhastigheds AES-256 kryptering ved hjælp af opdelt streaming (chunked streaming) understøttes indbygget i HotPDF VCL Component.