Dans les secteurs juridique, financier et de la santé, la génération de gros volumes de documents PDF est une pratique courante. Cependant, la production des documents ne représente que la moitié du travail ; les sécuriser est tout aussi critique. Lorsque vous disposez d'un pipeline d'archivage traitant des centaines de gigaoctets de PDF par jour, l'application du chiffrement AES-256 peut rapidement devenir un goulot d'étranglement des performances.
Dans cet article, nous explorerons comment obtenir un chiffrement PDF AES-256 à haute vitesse dans Delphi en évitant l'épuisement de la mémoire et en optimisant les boucles cryptographiques.
La spécification de chiffrement PDF
La sécurité des PDF a considérablement évolué. Les premières versions utilisaient le RC4 40 bits, qui est trivialement cassable aujourd'hui. La norme actuelle (PDF 1.7 niveau d'extension 3 et PDF 2.0) impose le chiffrement AES-256.
Dans un PDF, vous ne chiffrez pas le bloc de fichier entier. La structure du document (la table XRef et la structure des dictionnaires) reste en texte brut. Au lieu de cela, vous chiffrez les Flux (Streams) (les données brutes pour les images et le contenu de la page) et les Chaînes (Strings) (telles que le texte des métadonnées). Cela nécessite que l'analyseur extraie les données, applique le chiffrement AES CBC (Cipher Block Chaining) et les réécrive.
Le goulot d'étranglement : chargement en mémoire
Une erreur courante lors du chiffrement d'un PDF massif (par exemple, une archive numérisée de 2 Go) consiste à charger l'intégralité du flux dans un TMemoryStream avant de le transmettre au moteur cryptographique. Cela entraîne des exceptions de mémoire insuffisante (Out-Of-Memory, OOM) dans les processus 32 bits et des défauts de page massifs dans les processus 64 bits.
Chiffrement en continu (Streaming) dans Delphi
La solution consiste à utiliser une approche de diffusion en continu fragmentée. En utilisant l'API de cryptographie Windows : Next Generation (CNG) ou une bibliothèque comme OpenSSL, vous pouvez lire le flux PDF en blocs de 64 Ko, chiffrer le bloc et l'écrire directement dans le flux de disque de sortie.
Voici un exemple conceptuel Delphi démontrant une boucle de chiffrement en mémoire tampon pour 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;
Optimisation du backend cryptographique
Les développeurs Delphi disposent de plusieurs choix pour le backend AES :
- Implémentations Delphi natives : Faciles à déployer, mais souvent plus lentes car elles s'exécutent uniquement au niveau logiciel.
- Windows CNG (BCrypt) : Hautement optimisé et peut utiliser l'accélération matérielle (instructions AES-NI sur les processeurs Intel/AMD modernes).
- OpenSSL (libcrypto) : La norme de l'industrie, incroyablement rapide, mais nécessite l'expédition de DLL externes.
Pour les applications serveur à haut débit, l'accélération matérielle AES-NI est obligatoire. Lors de l'utilisation de Windows CNG dans Delphi, le mappage de la fonction BCryptEncrypt permet à votre application de décharger le travail lourd sur le silicium cryptographique dédié du processeur, réduisant ainsi la surcharge de chiffrement à presque zéro.
Conclusion
Lors du chiffrement de PDF à l'échelle du gigaoctet, fiez-vous au fractionnement des flux plutôt qu'à la mise en mémoire tampon complète, et assurez-vous que votre backend cryptographique utilise l'accélération matérielle AES-NI. Cette combinaison garantit que votre pipeline d'archivage s'exécute à la vitesse de vos disques NVMe, plutôt que d'être limité par le processeur.
Remarque : Le chiffrement AES-256 à haute vitesse utilisant la diffusion en continu fragmentée est pris en charge de manière native dans le composant VCL HotPDF.