Skip to content

高级加密

Pro — Commercial License Required
高级加密功能需要 Pro 包。

TCPDF-Next 仅支持 AES-256 加密(AESV3 加密处理器,Revision 6),这是 PDF 2.0 标准中唯一推荐的加密方式。Pro 包提供底层加密机制的完整控制,包括密钥推导、密码规范化与权限编码。

安全策略

项目策略
支持的加密AES-256(AESV3,Revision 6)
不支持的加密RC4 40-bit、RC4 128-bit、AES-128
密钥推导基于密码的密钥推导(PDF 2.0 规范)
密码规范化SASLprep(RFC 4013)
密码最大长度127 字节(UTF-8 编码后)

TCPDF-Next 刻意不支持 RC4 与 AES-128,因为这些算法已被视为不安全。如果需要打开使用旧加密方式的既有文件,请使用专门的 PDF 处理工具。

AES-256 AESV3 详解

加密架构

密码 → SASLprep 规范化 → 密钥推导 → 256-bit 加密密钥

                              AES-256-CBC 加密每个流与字符串

基本加密

php
use Yeeefang\TcpdfNext\Core\Document;

$pdf = Document::create()
    ->addPage()
    ->font('Helvetica', size: 12)
    ->text('此文件使用 AES-256 加密保护。');

$pdf->encrypt(
    userPassword: 'reader-pass',
    ownerPassword: 'owner-pass'
);

$pdf->save('/output/encrypted.pdf');

密钥推导

PDF 2.0 的密钥推导流程基于以下步骤:

  1. 密码规范化:使用 SASLprep 将密码转为标准形式。
  2. 哈希计算:使用 SHA-256 计算密码哈希。
  3. 密钥加密密钥:生成随机的 Key Encryption Key(KEK)。
  4. 文件加密密钥:生成随机的 File Encryption Key(FEK)。
  5. 密钥包装:使用 KEK 包装 FEK,存储在加密字典中。
php
use Yeeefang\TcpdfNext\Pro\Security\Encryption\Aes256Encryptor;

$encryptor = new Aes256Encryptor();

// 底层密钥推导(通常不需手动调用)
$keys = $encryptor->deriveKeys(
    userPassword: 'reader-pass',
    ownerPassword: 'owner-pass'
);

SASLprep 密码规范化

SASLprep(RFC 4013)确保不同平台、不同输入法输入的相同密码会被统一处理:

php
use Yeeefang\TcpdfNext\Pro\Security\Encryption\SaslPrep;

$normalized = SaslPrep::prepare('Password');  // 全角转半角
// 结果:'Password'

$normalized = SaslPrep::prepare("caf\u{00E9}");       // NFC 规范化
// 结果:'caf' + U+00E9

SASLprep 处理规则

步骤说明
映射移除不可打印字符,全角转半角
规范化Unicode NFKC 规范化
禁止字符拒绝控制字符、私用区字符等
双向检查验证混合方向文字的正确性

权限编码

PDF 2.0 使用 32-bit 标志编码文件权限。Pro 包提供类型安全的权限配置:

php
use Yeeefang\TcpdfNext\Contracts\Enums\Permission;

$pdf->encrypt(
    userPassword: '',               // 空字符串 = 打开不需密码
    ownerPassword: 'admin-pass',
    permissions: [
        Permission::Print,
        Permission::PrintHighQuality,
    ]
);

权限标志映射

权限位位置说明
Print3打印(可能为低分辨率)
Modify4修改文件内容
Copy5复制或提取文字
Annotate6新增或修改注解
FillForms9填写表单字段
ExtractForAccessibility10为辅助技术提取内容
Assemble11组装文件
PrintHighQuality12高品质打印

不设权限限制

php
$pdf->encrypt(
    userPassword: 'secure-pass',
    ownerPassword: 'admin-pass',
    permissions: Permission::all()   // 授予所有权限
);

与 PDF/A 的关系

PDF/A 标准明确禁止加密。如果同时启用加密与 PDF/A 合规,PdfAManager 会在验证阶段报告错误。数字签名不属于加密,PDF/A 文件可以正常使用数字签名。

下一步

以 LGPL-3.0-or-later 许可证发布。