在法律、金融與醫療保健領域,產生大量的 PDF 文件是標準做法。然而,產生文件只成功了一半;保護它們的安全同樣重要。當您有一個每天處理數百 GB PDF 的歸檔管線時,套用 AES-256 加密很快就會成為效能瓶頸。
在本文中,我們將探討如何透過避免記憶體耗盡並最佳化加密迴圈,在 Delphi 中實現高速 AES-256 PDF 加密。
PDF 加密規範
PDF 的安全性已有了顯著的演進。早期版本使用 40 位元的 RC4,這在今天很容易被破解。目前的標準 (PDF 1.7 延伸層級 3 與 PDF 2.0) 強制要求使用 AES-256 加密。
在 PDF 中,您不會加密整個檔案區塊。文件結構 (XRef 表格與字典的結構) 保持明文。相反地,您會加密串流 (Streams) (圖片與頁面內容的原始資料) 與字串 (Strings) (例如詮釋資料文字)。這需要解析器擷取資料,套用 AES CBC (密碼區塊連結),然後將其寫回。
瓶頸:載入記憶體
加密大型 PDF (例如 2GB 的掃描存檔) 時常見的錯誤是,在將串流傳遞給密碼引擎之前,將整個串流載入 TMemoryStream 中。這會導致在 32 位元處理程序中發生記憶體不足 (OOM) 例外,以及在 64 位元處理程序中產生大量的分頁錯誤。
在 Delphi 中進行串流加密
解決方案是採用分塊的串流處理方法。使用 Windows 密碼編譯 API:次世代 (CNG) 或類似 OpenSSL 的函式庫,您可以讀取 64KB 區塊的 PDF 串流,加密該區塊,並將其直接寫入輸出磁碟串流。
以下是一個概念性的 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):高度最佳化,可利用硬體加速 (現代 Intel/AMD CPU 上的 AES-NI 指令)。
- OpenSSL (libcrypto):業界標準,速度極快,但需要隨附外部 DLL。
對於高吞吐量的伺服器應用程式,硬體加速的 AES-NI 是必備的。在 Delphi 中使用 Windows CNG 時,對映 BCryptEncrypt 函式允許您的應用程式將繁重的工作卸載到 CPU 專用的加密矽晶片上,有效地將加密負擔減少到近乎零。
結論
當加密 GB 級的 PDF 時,請依賴串流分塊而非完整的記憶體緩衝,並確保您的加密後端利用硬體 AES-NI 加速。這個組合保證了您的歸檔管線能以您的 NVMe 磁碟機的速度運作,而不是受限於 CPU。
備註:HotPDF VCL 元件 原生支援利用分塊串流的高速 AES-256 加密。