高级加密
★ 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 的密钥推导流程基于以下步骤:
- 密码规范化:使用 SASLprep 将密码转为标准形式。
- 哈希计算:使用 SHA-256 计算密码哈希。
- 密钥加密密钥:生成随机的 Key Encryption Key(KEK)。
- 文件加密密钥:生成随机的 File Encryption Key(FEK)。
- 密钥包装:使用 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+00E9SASLprep 处理规则
| 步骤 | 说明 |
|---|---|
| 映射 | 移除不可打印字符,全角转半角 |
| 规范化 | 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,
]
);权限标志映射
| 权限 | 位位置 | 说明 |
|---|---|---|
Print | 3 | 打印(可能为低分辨率) |
Modify | 4 | 修改文件内容 |
Copy | 5 | 复制或提取文字 |
Annotate | 6 | 新增或修改注解 |
FillForms | 9 | 填写表单字段 |
ExtractForAccessibility | 10 | 为辅助技术提取内容 |
Assemble | 11 | 组装文件 |
PrintHighQuality | 12 | 高品质打印 |
不设权限限制
php
$pdf->encrypt(
userPassword: 'secure-pass',
ownerPassword: 'admin-pass',
permissions: Permission::all() // 授予所有权限
);与 PDF/A 的关系
PDF/A 标准明确禁止加密。如果同时启用加密与 PDF/A 合规,PdfAManager 会在验证阶段报告错误。数字签名不属于加密,PDF/A 文件可以正常使用数字签名。
下一步
- PAdES 数字签名 — 数字签名与加密是独立功能。
- PDF/A-4 归档 — 了解为何 PDF/A 禁止加密。
- 授权 — Pro 包的商业授权条款。