Skip to content

加密 (HasSecurity)

Document 上的 HasSecurity trait 透過 Aes256Encryptor 引擎提供 AES-256 加密。TCPDF-Next 僅實作 PDF 2.0 安全處理器(AESV3, Revision 6, V5)— RC4 與 AES-128 已被刻意移除。密碼透過 SASLprep(RFC 4013)進行正規化以正確處理 Unicode,金鑰衍生則使用 Algorithm 2.B(迭代 SHA-256/384/512)。

快速參考

方法說明
setProtection()啟用 AES-256 加密,設定權限與密碼

啟用加密

php
use Yeeefang\TcpdfNext\Core\Document;

$pdf = Document::create()
    ->setProtection(
        permissions: ['print', 'copy'],
        userPass: 'reader-password',
        ownerPass: 'owner-secret-password',
    )
    ->addPage()
    ->setFont('Helvetica', '', 12)
    ->cell(0, 10, 'This PDF is AES-256 encrypted', newLine: true)
    ->save('encrypted.pdf');

setProtection() 回傳 static,可與所有其他 Document 方法鏈式串接。

php
$pdf->setProtection(
    array  $permissions = [],   // 權限旗標(參見下表)
    string $userPass    = '',   // 開啟文件所需的密碼
    string $ownerPass   = '',   // 取得完整存取權限的密碼
);

使用者密碼 vs 擁有者密碼

  • 使用者密碼 — 讀者必須輸入此密碼才能開啟並檢視 PDF。留空時文件無需提示即可開啟,但權限限制仍然有效。
  • 擁有者密碼 — 授予文件的完整存取權限,繞過所有權限限制。留空時,系統會在內部自動產生隨機 32 位元組的擁有者密碼。

兩種密碼在金鑰衍生前都會經過 SASLprep(RFC 4013)正規化處理,確保 Unicode 密碼(如 "Pässwörd")在所有 PDF 閱讀器中的行為一致。

權限旗標

$permissions 陣列中傳入以下字串旗標的任意組合:

旗標說明
print允許列印(低解析度)
modify允許修改內容
copy允許擷取文字與圖片
annotate允許新增註解
fill-forms允許填寫表單欄位
extract允許無障礙擷取
assemble允許插入、旋轉與刪除頁面
print-highres允許高解析度列印

$permissions 為空時,所有操作皆受限制(需要擁有者密碼才能執行任何動作)。

僅擁有者加密

限制權限但不要求開啟密碼:

php
use Yeeefang\TcpdfNext\Core\Document;

$pdf = Document::create()
    ->setProtection(
        permissions: ['print', 'fill-forms'],
        ownerPass: 'admin-password',
    )
    ->addPage()
    ->setFont('Helvetica', '', 12)
    ->cell(0, 10, 'Open freely, but only print and fill forms.', newLine: true)
    ->save('restricted.pdf');

文件無需密碼即可開啟,但修改、複製與註解功能會被封鎖,除非提供擁有者密碼。

安全架構

TCPDF-Next 專門實施最強的 PDF 加密標準:

  • 演算法: AES-256-CBC (AESV3), Revision 6, V5
  • 金鑰長度: 256 位元
  • 無舊版支援: RC4 與 AES-128 已被刻意移除

SASLprep 密碼正規化

SaslPrep 類別(RFC 4013)透過 NFKC Unicode 正規化處理密碼、拒絕禁用字元,並強制執行雙向文字約束。這確保無論平台或輸入方式為何,都能產生相同的雜湊值。

金鑰衍生 — Algorithm 2.B

ISO 32000-2 的 Algorithm 2.B 透過迭代 SHA-256/384/512 雜湊(最多 64 輪)衍生加密金鑰,提供強大的暴力破解抵抗能力。

PDF/A 不相容

PDF/A 合規文件不允許加密。若嘗試在已啟用 PDF/A 模式的文件上呼叫 setProtection(),將拋出 PdfAException

php
use Yeeefang\TcpdfNext\Core\Document;

// 這會拋出 PdfAException
$pdf = Document::create()
    ->setPdfA(true)
    ->setProtection(permissions: ['print'], ownerPass: 'secret');
// -> throws PdfAException: "Encryption is not allowed in PDF/A documents"

若同時需要典藏合規性與存取控制,請考慮改用具有權限限制的數位簽章。

完整範例

php
use Yeeefang\TcpdfNext\Core\Document;

$pdf = Document::create()
    ->setTitle('Confidential Report')
    ->setAuthor('Security Team')
    ->setProtection(
        permissions: ['print-highres', 'copy'],
        userPass: 'open-me',
        ownerPass: 'full-access-2026',
    )
    ->addPage()
    ->setFont('Helvetica', 'B', 18)
    ->cell(0, 15, 'Confidential Report', newLine: true)
    ->setFont('Helvetica', '', 12)
    ->multiCell(0, 6, 'This document is protected with AES-256 encryption. '
        . 'Readers can print and copy, but cannot modify or annotate.')
    ->save('confidential-report.pdf');

以 LGPL-3.0-or-later 授權釋出。