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 许可证发布。