跳到內容

以 AES-256 加密 PDF 並設定權限

這則 recipe(範例)會以 AES-256 加密一份文件。它會設定一組使用者密碼與一組擁有者密碼,並透過權限位元遮罩限制各項操作。本範例依循 examples/22-protection.php

可重現性:為什麼這則範例是 structural,而非 bitwise 一份 AES-256 PDF 即使輸入與密碼都相同,也不可能在兩次執行之間做到逐 byte 完全相同。修訂版 6 的標準安全處理常式,每次加密都會透過強隨機亂數產生器產生 16 個全新的隨機位元組(user/owner 驗證鹽與金鑰鹽), 然後才據以推導出檔案加密金鑰 (ISO 32000-2 §7.6.4 的金鑰衍生雜湊演算法)。 AES-256-CBC 對每個物件都使用一組隨機初始化向量。檔案 trailer 中的 /ID 同樣是由兩個位元組字串組成的陣列,其第一個元素是一個在建立時就由檔案推導出的永久識別碼(ISO 32000-2 §14.4)。 因此,它的可重現性屬於 structural:測試載具會把加密鹽/IV、物件順序與 trailer 的 /ID 正規化之後,再比對兩次執行,而不是斷言一個不可能成立的逐 byte 相符。

  • 已安裝核心套件:composer require nextpdf/core:^3
  • AES-256 加密器需要使用 openssl PHP 擴充功能。
  1. 建立文件。
  2. 呼叫 setEncryption()務必addPage() 之前。在寫入任何內容物件之前,加密器就必須先存在。
  3. 傳入一組使用者密碼(開啟文件時必須提供)、一組擁有者密碼(完整存取權)以及一個權限位元遮罩。
  4. 加入內容並儲存。寫入器會加密每一個物件主體。
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
// Permission bits (ISO 32000-2, encryption dictionary P entry):
// bit 3 (4) allow printing
// bit 4 (8) allow content modification
// bit 5 (16) allow text extraction / copying
// bit 6 (32) allow annotation and form editing
// Grant printing only:
$permissions = 4;
$doc = Document::createStandalone();
$doc->setTitle('Encrypted Document');
// setEncryption() MUST run before addPage(). Order matters.
$doc->setEncryption(
userPassword: 'open-me',
ownerPassword: 'owner-secret',
permissions: $permissions,
);
$doc->addPage();
$doc->setFont('helvetica', '', 12);
$doc->cell(0, 10, 'This document is encrypted with AES-256.', newLine: true);
$doc->save(__DIR__ . '/encrypted.pdf');
echo "Wrote encrypted.pdf (AES-256, printing only)\n";
Wrote encrypted.pdf (AES-256, printing only)

開啟 encrypted.pdf 時會要求輸入密碼。使用者密碼會以受限的權限集合開啟文件;擁有者密碼則會以完整存取權開啟文件。

  • 呼叫順序。 若把 setEncryption() 排在 addPage() 之後才呼叫,並不會回頭把先前的內容加密。請務必先設定好加密。
  • 擁有者密碼預設值。 當擁有者密碼為空時,引擎會改用使用者密碼作為擁有者密碼。當這兩種角色必須有所區別時,請設定不同的密碼。
  • 權限語意:邊界。 這些權限位元由符合規範的閱讀器遵守。它們並非以密碼學方式強制執行:忽略這些位元的閱讀器,或搭配擁有者密碼使用的工具,仍可執行受限的操作。請將權限視為對協作軟體發出的政策訊號,而不是能抵擋有心人士的存取控制。
  • PDF/A 衝突。 PDF/A 禁止使用 Encrypt trailer 鍵。對 PDF/A 文件呼叫 setEncryption(),無論順序如何,都會擲出不相容例外。請參閱 PDF/A-4 一致性 gate
  • AES-256-GCM。 當主機的 OpenSSL 或 libsodium 提供此加密法時,useAesGcm() 會選用 ISO/TS 32003 的 GCM 大量加密。否則它會擲出 InvalidConfigException
陳述規範條款參考 ID
標準安全處理常式定義了加密演算法與金鑰長度。ISO 32000-2§7.6
加密字典的 P 項目帶有權限位元。ISO 32000-2§7.6

加密會為沒有密碼的各方保護內容機密性。權限位元對閱讀器而言只是建議性的,單憑它們本身並不能阻止不符合規範的工具進行操作。