Technical Article

Κρυπτογράφηση PDF Υψηλής Ταχύτητας AES-256 για Τεράστια Έγγραφα

Στον νομικό, οικονομικό και υγειονομικό τομέα, η παραγωγή μεγάλου όγκου εγγράφων PDF αποτελεί τυπική πρακτική. Ωστόσο, η παραγωγή των εγγράφων είναι μόνο η μισή μάχη· η ασφάλισή τους είναι εξίσου κρίσιμη. Όταν έχετε μια γραμμή αρχειοθέτησης που επεξεργάζεται εκατοντάδες gigabytes από PDF καθημερινά, η εφαρμογή κρυπτογράφησης AES-256 μπορεί γρήγορα να αποτελέσει σημείο συμφόρησης (bottleneck) στην απόδοση.

Σε αυτό το άρθρο, θα εξερευνήσουμε πώς να επιτύχετε κρυπτογράφηση PDF υψηλής ταχύτητας με AES-256 στο Delphi, αποφεύγοντας την εξάντληση μνήμης και βελτιστοποιώντας τους κρυπτογραφικούς βρόχους.

Η Προδιαγραφή Κρυπτογράφησης PDF

Η ασφάλεια των PDF έχει εξελιχθεί σημαντικά. Οι πρώτες εκδόσεις χρησιμοποιούσαν το RC4 των 40-bit, το οποίο σπάει πολύ εύκολα σήμερα. Το τρέχον πρότυπο (PDF 1.7 Extension Level 3 και PDF 2.0) επιβάλλει κρυπτογράφηση AES-256.

Σε ένα PDF, δεν κρυπτογραφείτε ολόκληρο το μπλοκ του αρχείου. Η δομή του εγγράφου (ο πίνακας XRef και η δομή των λεξικών) παραμένει σε απλό κείμενο (plaintext). Αντίθετα, κρυπτογραφείτε τις Ροές (Streams - τα ακατέργαστα δεδομένα για εικόνες και περιεχόμενο σελίδας) και τις Συμβολοσειρές (Strings - όπως το κείμενο μεταδεδομένων). Αυτό απαιτεί από τον αναλυτή να εξαγάγει τα δεδομένα, να εφαρμόσει AES CBC (Cipher Block Chaining) και να τα γράψει ξανά.

Το Σημείο Συμφόρησης: Φόρτωση στη Μνήμη

Ένα συνηθισμένο λάθος κατά την κρυπτογράφηση ενός τεράστιου PDF (π.χ., ενός σαρωμένου αρχείου 2GB) είναι η φόρτωση ολόκληρης της ροής σε ένα TMemoryStream πριν περαστεί στην κρυπτογραφική μηχανή. Αυτό οδηγεί σε εξαιρέσεις Έλλειψης Μνήμης (Out-Of-Memory - OOM) σε διεργασίες 32-bit και μαζικά σφάλματα σελίδας (page faulting) σε διεργασίες 64-bit.

Κρυπτογράφηση Ροής στο Delphi

Η λύση είναι να χρησιμοποιήσετε μια προσέγγιση ροής σε κομμάτια (chunked). Χρησιμοποιώντας το Windows Cryptography API: Next Generation (CNG) ή μια βιβλιοθήκη όπως το OpenSSL, μπορείτε να διαβάσετε τη ροή PDF σε μπλοκ των 64KB, να κρυπτογραφήσετε το μπλοκ και να το γράψετε απευθείας στη ροή δίσκου εξόδου.

Ακολουθεί ένα εννοιολογικό παράδειγμα Delphi που δείχνει έναν βρόχο κρυπτογράφησης με buffer για μια ροή:

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;

Βελτιστοποίηση του Κρυπτογραφικού Backend

Οι προγραμματιστές Delphi έχουν πολλές επιλογές για το AES backend:

  • Εγγενείς υλοποιήσεις Delphi: Εύκολες στην ανάπτυξη, αλλά συχνά πιο αργές καθώς εκτελούνται αμιγώς σε λογισμικό.
  • Windows CNG (BCrypt): Υψηλά βελτιστοποιημένο και μπορεί να χρησιμοποιήσει επιτάχυνση υλικού (εντολές AES-NI σε σύγχρονους επεξεργαστές Intel/AMD).
  • OpenSSL (libcrypto): Το βιομηχανικό πρότυπο, απίστευτα γρήγορο, αλλά απαιτεί την αποστολή εξωτερικών DLL.

Για εφαρμογές διακομιστή υψηλής απόδοσης (high-throughput), το επιταχυνόμενο από υλικό AES-NI είναι υποχρεωτικό. Όταν χρησιμοποιείτε Windows CNG στο Delphi, η χαρτογράφηση της συνάρτησης BCryptEncrypt επιτρέπει στην εφαρμογή σας να μεταθέσει τον βαρύ φόρτο στο αποκλειστικό κρυπτογραφικό πυρίτιο της CPU, μειώνοντας ουσιαστικά την επιβάρυνση (overhead) της κρυπτογράφησης σχεδόν στο μηδέν.

Συμπέρασμα

Κατά την κρυπτογράφηση PDF κλίμακας gigabyte, βασιστείτε στον διαχωρισμό ροής σε κομμάτια (stream chunking) αντί για πλήρη αποθήκευση σε προσωρινή μνήμη (full memory buffering) και βεβαιωθείτε ότι το κρυπτογραφικό σας backend χρησιμοποιεί επιτάχυνση υλικού AES-NI. Αυτός ο συνδυασμός εγγυάται ότι η γραμμή αρχειοθέτησής σας θα εκτελείται με την ταχύτητα των δίσκων NVMe, αντί να περιορίζεται από τη CPU.

Σημείωση: Η κρυπτογράφηση υψηλής ταχύτητας AES-256 που χρησιμοποιεί chunked streaming υποστηρίζεται εγγενώς στο HotPDF VCL Component.