У юридичному, фінансовому та медичному секторах створення великих обсягів PDF-документів є стандартною практикою. Однак створення документів — це лише половина справи; їх захист є не менш критичним. Коли у вас є архівний конвеєр, що щодня обробляє сотні гігабайт PDF-файлів, застосування шифрування AES-256 може швидко стати вузьким місцем у продуктивності.
У цій статті ми розглянемо, як досягти високошвидкісного шифрування PDF за допомогою AES-256 у Delphi, уникаючи вичерпання пам'яті та оптимізуючи криптографічні цикли.
Специфікація шифрування PDF
Безпека PDF значно еволюціонувала. Ранні версії використовували 40-бітний RC4, який сьогодні тривіально зламати. Поточний стандарт (PDF 1.7 Extension Level 3 і PDF 2.0) вимагає шифрування AES-256.
У PDF-файлі ви не шифруєте весь блок файлу. Структура документа (таблиця XRef і структура словників) залишається у вигляді звичайного тексту. Натомість ви шифруєте Потоки (Streams) (необроблені дані для зображень і вмісту сторінок) і Рядки (Strings) (наприклад, текст метаданих). Це вимагає від аналізатора вилучити дані, застосувати AES CBC (Cipher Block Chaining - зчеплення блоків шифротексту) і записати їх назад.
Вузьке місце: завантаження в пам'ять
Поширеною помилкою під час шифрування масивного PDF-файлу (наприклад, відсканованого архіву розміром 2 ГБ) є завантаження всього потоку в `TMemoryStream` перед передачею його криптографічному рушію. Це призводить до винятків Out-Of-Memory (OOM - брак пам'яті) у 32-бітних процесах і масових помилок сторінок (page faulting) у 64-бітних процесах.
Потокове шифрування в Delphi
Рішення полягає у використанні фрагментованого, потокового підходу. Використовуючи Windows Cryptography API: Next Generation (CNG) або бібліотеку на кшталт OpenSSL, ви можете читати потік PDF блоками по 64 КБ, шифрувати блок і записувати його безпосередньо у вихідний дисковий потік.
Ось концептуальний приклад на Delphi, що демонструє буферизований цикл шифрування для потоку:
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;
Оптимізація криптографічного бекенду
Розробники Delphi мають кілька варіантів для бекенду AES:
- Нативні реалізації Delphi: Легко розгортаються, але часто повільніші, оскільки виконуються суто програмно.
- Windows CNG (BCrypt): Високооптимізований і може використовувати апаратне прискорення (інструкції AES-NI на сучасних процесорах Intel/AMD).
- OpenSSL (libcrypto): Галузевий стандарт, неймовірно швидкий, але вимагає постачання зовнішніх файлів DLL.
Для високопродуктивних серверних додатків апаратно-прискорений AES-NI є обов'язковим. При використанні Windows CNG у Delphi зіставлення функції BCryptEncrypt дозволяє вашому додатку перекласти важку роботу на виділений криптографічний кремній процесора, ефективно зменшуючи накладні витрати на шифрування майже до нуля.
Висновок
Під час шифрування гігабайтних PDF-файлів покладайтеся на розбиття потоків на фрагменти, а не на повну буферизацію пам'яті, і переконайтеся, що ваш криптографічний бекенд використовує апаратне прискорення AES-NI. Ця комбінація гарантує, що ваш конвеєр архівування працюватиме зі швидкістю ваших накопичувачів NVMe, а не обмежуватиметься можливостями процесора.
Примітка: Високошвидкісне шифрування AES-256 із використанням фрагментованої потокової передачі нативно підтримується в компоненті HotPDF VCL.