Nei settori legale, finanziario e sanitario, la generazione di grandi volumi di documenti PDF è una pratica standard. Tuttavia, produrre i documenti è solo metà della battaglia; renderli sicuri è altrettanto fondamentale. Quando si dispone di una pipeline di archiviazione che elabora quotidianamente centinaia di gigabyte di PDF, l'applicazione della crittografia AES-256 può diventare rapidamente un collo di bottiglia per le prestazioni.
In questo articolo, esploreremo come ottenere la crittografia PDF AES-256 ad alta velocità in Delphi, evitando l'esaurimento della memoria e ottimizzando i cicli crittografici.
Le Specifiche della Crittografia PDF
La sicurezza dei PDF si è evoluta in modo significativo. Le prime versioni utilizzavano RC4 a 40 bit, che oggi è facilmente violabile. Lo standard attuale (PDF 1.7 Extension Level 3 e PDF 2.0) richiede la crittografia AES-256.
In un PDF, non si crittografa l'intero blocco del file. La struttura del documento (la tabella XRef e la struttura dei dizionari) rimane in chiaro. Si crittografano invece i Flussi (i dati grezzi per le immagini e il contenuto della pagina) e le Stringhe (come il testo dei metadati). Ciò richiede che il parser estragga i dati, applichi l'AES CBC (Cipher Block Chaining) e li scriva nuovamente.
Il Collo di Bottiglia: Caricamento in Memoria
Un errore comune quando si crittografa un PDF di grandi dimensioni (ad esempio, un archivio scansionato da 2 GB) è caricare l'intero flusso in un TMemoryStream prima di passarlo al motore crittografico. Ciò porta a eccezioni di Out-Of-Memory (OOM) nei processi a 32 bit e a massicci page fault nei processi a 64 bit.
Crittografia in Streaming in Delphi
La soluzione consiste nell'utilizzare un approccio in streaming a blocchi. Utilizzando l'API Windows Cryptography: Next Generation (CNG) o una libreria come OpenSSL, è possibile leggere il flusso PDF in blocchi da 64 KB, crittografare il blocco e scriverlo direttamente sul flusso del disco di output.
Ecco un esempio concettuale in Delphi che dimostra un ciclo di crittografia bufferizzata per un flusso:
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;
Ottimizzare il Backend Crittografico
Gli sviluppatori Delphi hanno diverse opzioni per il backend AES:
- Implementazioni Delphi native: facili da distribuire, ma spesso più lente poiché vengono eseguite esclusivamente via software.
- Windows CNG (BCrypt): altamente ottimizzato e in grado di utilizzare l'accelerazione hardware (istruzioni AES-NI sulle moderne CPU Intel/AMD).
- OpenSSL (libcrypto): lo standard di settore, incredibilmente veloce, ma richiede la distribuzione di DLL esterne.
Per le applicazioni server ad alto rendimento, l'accelerazione hardware AES-NI è obbligatoria. Quando si usa Windows CNG in Delphi, la mappatura della funzione BCryptEncrypt consente alla tua applicazione di scaricare il lavoro pesante sul silicio crittografico dedicato della CPU, riducendo di fatto a zero l'overhead della crittografia.
Conclusione
Quando si crittografano PDF su scala gigabyte, affidati alla suddivisione in blocchi del flusso anziché al buffering in memoria completa, e assicurati che il tuo backend crittografico utilizzi l'accelerazione hardware AES-NI. Questa combinazione garantisce che la tua pipeline di archiviazione funzioni alla velocità dei tuoi dischi NVMe, invece di essere limitata dalla CPU.
Nota: la crittografia AES-256 ad alta velocità che utilizza lo streaming a blocchi è supportata nativamente nel Componente VCL HotPDF.