跳转到内容

使用 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 时会要求输入密码。使用用户密码时,会在受限的权限集合下打开文档。使用所有者密码时,则会以完整访问权限打开文档。

  • 调用顺序。 如果在 addPage() 之后才调用 setEncryption(),它不会回头加密此前写入的内容。请务必先配置好加密。
  • 所有者密码默认值。 所有者密码为空时,引擎会改用用户密码作为所有者密码。如果这两种角色必须区分开,请设置不同的密码。
  • 权限语义:边界。 这些权限位由符合规范的阅读器遵守。它们并不是通过密码学手段强制执行的:忽略这些位的阅读器,或搭配所有者密码使用的工具,仍可执行受限的操作。请将权限视为发送给协作软件的策略信号,而不是能够抵御有意规避者的访问控制。
  • 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

对于没有密码的各方,加密会保护内容的机密性。权限位对阅读器而言只是建议性的,单凭它们本身并不能阻止不符合规范的工具进行操作。