A jogi, pénzügyi és egészségügyi szektorban nagy mennyiségű PDF-dokumentum generálása mindennapos gyakorlat. A dokumentumok előállítása azonban csak a csata fele; biztonságuk garantálása legalább ennyire kritikus. Amikor egy archiválási folyamat naponta több száz gigabájtnyi PDF-et dolgoz fel, az AES-256 titkosítás alkalmazása gyorsan teljesítménybeli szűk keresztmetszetté válhat.
Ebben a cikkben megvizsgáljuk, hogyan érhető el nagy sebességű AES-256 PDF-titkosítás Delphiben a memóriakimerülés elkerülésével és a kriptográfiai ciklusok optimalizálásával.
A PDF titkosítás specifikációja
A PDF-biztonság jelentősen fejlődött. A korai verziók 40 bites RC4-et használtak, amely ma már triviálisan feltörhető. A jelenlegi szabvány (PDF 1.7 Extension Level 3 és PDF 2.0) az AES-256 titkosítást írja elő.
Egy PDF-ben nem a teljes fájlblokkot titkosítják. A dokumentumstruktúra (az XRef tábla és a szótárak felépítése) egyszerű szövegként (plaintext) marad. Ehelyett a Streameket (a képek és az oldaltartalom nyers adatai) és a Karakterláncokat (például a metaadatszövegek) titkosítják. Ehhez az elemzőnek ki kell nyernie az adatokat, alkalmaznia kell az AES CBC-t (Cipher Block Chaining), majd vissza kell írnia azokat.
A szűk keresztmetszet: Betöltés a memóriába
Gyakori hiba egy hatalmas (pl. egy 2 GB-os szkennelt archívum) PDF titkosításakor a teljes stream betöltése egy TMemoryStream-be, mielőtt átadná azt a kriptográfiai motornak. Ez 32 bites folyamatoknál Out-Of-Memory (OOM) kivételekhez, 64 bites folyamatoknál pedig masszív lapozási hibákhoz vezet.
Folyamatos (Streaming) titkosítás Delphiben
A megoldás egy darabolt, folyamatos (streaming) megközelítés alkalmazása. A Windows Cryptography API: Next Generation (CNG) vagy egy olyan könyvtár használatával, mint az OpenSSL, beolvashatja a PDF streamet 64 KB-os blokkokban, titkosíthatja a blokkot, majd közvetlenül a kimeneti lemezstreamre írhatja.
Íme egy koncepcionális Delphi példa, amely egy stream pufferelt titkosítási ciklusát mutatja be:
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;
A kriptográfiai háttér optimalizálása
A Delphi fejlesztők számos lehetőség közül választhatnak az AES háttérhez:
- Natív Delphi implementációk: Könnyen telepíthetők, de gyakran lassabbak, mivel tisztán szoftveresen futnak.
- Windows CNG (BCrypt): Magasan optimalizált, és képes kihasználni a hardveres gyorsítást (AES-NI utasítások a modern Intel/AMD CPU-kon).
- OpenSSL (libcrypto): Az ipari szabvány, hihetetlenül gyors, de külső DLL-ek szállítását igényli.
Nagy áteresztőképességű szerveralkalmazásokhoz a hardveres gyorsítású AES-NI kötelező. Ha a Windows CNG-t használja Delphiben, a BCryptEncrypt függvény leképezése lehetővé teszi az alkalmazás számára, hogy a nehéz munkát a CPU dedikált kriptográfiai szilíciumára hárítsa át, amivel a titkosítási többletköltséget hatékonyan majdnem nullára csökkenti.
Összegzés
Gigabájtos méretű PDF-ek titkosításakor a teljes memóriapufferelés helyett támaszkodjon a stream darabolásra (chunking), és győződjön meg arról, hogy kriptográfiai háttere kihasználja a hardveres AES-NI gyorsítást. Ez a kombináció garantálja, hogy archiválási folyamata az NVMe meghajtók sebességével fusson, ahelyett, hogy a CPU korlátozná.
Megjegyzés: A darabolt streaminget alkalmazó nagy sebességű AES-256 titkosítást natívan támogatja a HotPDF VCL Component.