U pravnom, finansijskom i zdravstvenom sektoru, generisanje velike količine PDF dokumenata je standardna praksa. Međutim, proizvodnja dokumenata je samo pola bitke; njihovo obezbeđivanje je podjednako važno. Kada imate cevovod za arhiviranje koji svakodnevno obrađuje stotine gigabajta PDF-ova, primena AES-256 šifrovanja može brzo postati usko grlo u performansama.
U ovom članku ćemo istražiti kako postići brzo AES-256 PDF šifrovanje u Delphiju izbegavanjem iscrpljivanja memorije i optimizacijom kriptografskih petlji.
Specifikacija za šifrovanje PDF-a
Bezbednost PDF-a je značajno evoluirala. Rane verzije su koristile 40-bitni RC4, koji je danas trivijalno provaliti. Trenutni standard (PDF 1.7 Extension Level 3 i PDF 2.0) nalaže AES-256 šifrovanje.
U PDF-u, vi ne šifrujete ceo blok datoteke. Struktura dokumenta (XRef tabela i struktura rečnika) ostaje u običnom tekstu. Umesto toga, šifrujete tokove (Streams) (sirove podatke za slike i sadržaj stranice) i stringove (kao što je tekst metapodataka). Ovo zahteva od parsera da izdvoji podatke, primeni AES CBC (Cipher Block Chaining) i da ih ponovo upiše.
Usko grlo: Učitavanje u memoriju
Česta greška prilikom šifrovanja masivnog PDF-a (npr. skenirane arhive od 2GB) je učitavanje celog toka u TMemoryStream pre nego što se prosledi kriptografskom mehanizmu. Ovo dovodi do izuzetaka zbog nedostatka memorije (Out-Of-Memory) u 32-bitnim procesima i ogromnog broja grešaka pri učitavanju stranica (page faulting) u 64-bitnim procesima.
Strimovanje šifrovanja u Delphiju
Rešenje je korišćenje striming pristupa u delovima (chunked). Koristeći Windows Cryptography API: Next Generation (CNG) ili biblioteku kao što je OpenSSL, možete čitati PDF tok u blokovima od 64KB, šifrovati blok i upisati ga direktno u izlazni disk tok.
Evo konceptualnog primera u Delphiju koji demonstrira baferovanu petlju šifrovanja 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 kriptografskog pozadinskog sistema
Delphi programeri imaju nekoliko izbora za AES pozadinski sistem:
- Nativne Delphi implementacije: Jednostavne za primenu, ali često sporije jer se izvršavaju isključivo softverski.
- Windows CNG (BCrypt): Visoko optimizovan i može da iskoristi hardversko ubrzanje (AES-NI instrukcije na modernim Intel/AMD procesorima).
- OpenSSL (libcrypto): Industrijski standard, neverovatno brz, ali zahteva isporuku eksternih DLL datoteka.
Za serverske aplikacije visokog protoka, hardverski ubrzan AES-NI je obavezan. Kada koristite Windows CNG u Delphiju, mapiranje BCryptEncrypt funkcije omogućava vašoj aplikaciji da prebaci teške operacije na namenski kriptografski silicijum procesora, efektivno smanjujući troškove šifrovanja na skoro nulu.
Zaključak
Kada šifrujete PDF-ove u gigabajtnim razmerama, oslonite se na rad u delovima (chunking) umesto na potpuno baferovanje memorije, i osigurajte da vaš kriptografski pozadinski sistem koristi hardversko AES-NI ubrzanje. Ova kombinacija garantuje da će vaš cevovod za arhiviranje raditi brzinom vaših NVMe diskova, umesto da bude ograničen procesorom.
Napomena: Brzo AES-256 šifrovanje koje koristi strimovanje u delovima je nativno podržano u HotPDF VCL komponenti.