compat-legacy 安全与运维
本适配器沿用 NextPDF 引擎的安全模型,并在旧版 TCPDF 6.2.13 之上加入少量有意设计的强化措施。本页会准确说明哪些功能可用、哪些不可用,不夸大能力。请仔细阅读签名一节——它的适用范围有意限定得很窄。
强化后的旧版行为
标题为“强化后的旧版行为”的章节三项历史遗留的 TCPDF 6.2.13 行为已出于安全考虑作出变更,且无法配置回不安全的形式:
| 考量项目 | 旧版 TCPDF 6.2.13 | 适配器 |
|---|---|---|
| 错误处理 | Error() 会调用 die() 并终止进程 | Error() 会抛出 RuntimeException。可观察、可捕获,且不会无声地终止进程。 |
| HTML 执行 | 某个转义机制可能会从标记中执行 PHP | K_TCPDF_CALLS_IN_HTML 常量固定为 false;标记无法触发 PHP 执行。 |
| 直接输出 | Output() 会回显到当前活动的输出缓冲区 | 输出会通过安全的目的地桥接器路由。它不会污染由调用方控制的输出缓冲区。 |
错误处理的变更遵循一项原则:调用方必须能够观察到失败,而不是让进程在没有可观测信号的情况下消失。OWASP ASVS 5.0 §16.5.3 指出,应用程序应以优雅且安全的方式失败,并防止 fail-open 情形。改为抛出异常而非 die,正是对该原则的落实。HTML 强化则移除了一处代码执行汇点。请将任何依赖旧行为的遗留代码视为待修正的缺陷,并在迁移期间参考 /integrations/tcpdf-compat/migration/. 进行修正。固定的条款摘要位于页面前置数据的 citations 中。
本适配器公开 TCPDF 的 SetProtection(),并委派给 NextPDF 引擎的标准安全处理器。
- 标准处理器使用 AES-256。出于签名兼容性考虑,旧版的
$mode参数仍会被接受,但会被忽略——无法通过此方法选用较弱的密码算法。在严格模式开启时,使用非默认的$mode会抛出异常,以强制迁移过程正视该参数(在tests/Unit/Compat/Tcpdf/TcpdfStrictModeTest.php中加以断言)。 - 若未提供所有者密码,本适配器会生成一个具备密码学强度的随机所有者密码,而非重复使用用户密码。这可防止仅拥有用户级访问权的用户取得文档的所有者级控制权。
- 基于证书(公钥)的加密并非通过
SetProtection()完成;其$pubkeys参数会被忽略。请改用本适配器公开的现代公钥加密入口点(setPublicKeyEncryption()),它会委派给引擎。
加密行为与 ISO 32000-2 §7 所述的标准安全处理器一致。该条款定义了加密字典条目,以及引擎所使用的 AES-256 标准处理器。本文档并未声称输出「默认即安全」或「防篡改」。它说明的是所使用的密码算法与所有者密码行为,也就是代码的实际行为。固定的条款摘要位于页面前置数据的 citations 中。
<?php
declare(strict_types=1);
require __DIR__ . '/vendor/autoload.php';
use NextPDF\Compat\Tcpdf\TCPDF;
$pdf = new TCPDF();$pdf->AddPage();$pdf->SetFont('helvetica', '', 12);$pdf->Cell(0, 10, 'Encrypted document');
// User password set; owner password auto-generated (strong, random).$pdf->SetProtection([], 'user-secret');
$pdf->Output(__DIR__ . '/encrypted.pdf', 'F');数字签名——范围声明
标题为“数字签名——范围声明”的章节请按字面理解本节。它有意采取保守立场。
- TCPDF 旧版的
setSignature()与addEmptySignatureAppearance()方法在面向核心引擎的适配器中未实现。它们在默认模式下不会执行任何操作,并在严格模式下抛出TcpdfNotImplementedException。 - 数字签名并非核心发行版可通过本适配器获得的能力。 基线签名支持受商业版 NextPDF 版本门控。
- 在具备商业版时,本适配器会公开一个现代签名入口点(
setSignatureV2()),它会委派给引擎。其默认配置文件为**基线(B-B)**配置文件。 - 本文档并未声称任何版本可通过本适配器生成加盖时间戳、长期验证或归档的签名配置文件。具体而言,它并未主张 B-T、B-LT 或 B-LTA 的行为。PAdES 基线规范 §6.1 定义了四个不同的基线级别——B-B、B-T、B-LT 与 B-LTA——各自有其要求。B-B 是基线级别,而更高的级别(时间戳、长期、归档)分别是独立且要求更高的配置文件。本兼容层的文档仅涵盖 B-B 基线级别。更高的级别明确不在范围内,此处不为任何版本主张这些级别。固定的条款摘要位于页面前置数据的
citations中。 - 任何地方都没有做出「已认证」、「保证」、「具有法律效力」或「符合 eIDAS 资格」的签名主张。签名正确性、信任锚策略与法律效力,是签名版本与调用方 PKI 的责任,而非本兼容层的责任。
如果你的迁移需要签名,请将其视为独立的工作项:在商业版上采用现代签名 API,并用独立的验证器验证所生成的签名。请勿依赖 TCPDF 的 setSignature() 调用——它在这里是无作用(no-op)。
出于签名兼容性考虑,旧版的 setTimeStamp() 方法会被接受并发出一条通知;它不会通过本适配器生成加盖时间戳的签名。
PDF/A 与符合性
标题为“PDF/A 与符合性”的章节出于签名兼容性考虑,构造函数的 pdfa 标志会被接受。PDF/A 归档符合性需要商业版 NextPDF 版本。本适配器公开 enablePdfA(),它会委派给引擎;当所需的版本不存在时,引擎会返回一条可据此处理的配置错误。本适配器不会一边声称符合 PDF/A,一边无声地生成不符合要求的文件。
输出一律为 PDF 2.0(ISO 32000-2)。ISO 32000-2 §7.5.2 规定,符合规范的写入器会将文档版本标识为 2.0,且不会在保存时将其降回较旧的版本。因此 setPDFVersion() 无法将目标降至较旧的版本(参见 /integrations/tcpdf-compat/method-coverage/ §4)。固定的条款摘要位于页面前置数据的 citations 中。
运维指引
标题为“运维指引”的章节- 不会终止进程。 由于
Error()会抛出异常而非调用die(),请用try/catch包裹渲染入口点,并将失败映射到你的应用程序错误契约。请勿假设渲染失败就会结束请求。 - 输出缓冲区安全。
Output()与S配合会返回字节;与F配合会写入文件;与E配合会返回 base64 MIME 主体;与I/D配合则会通过引擎输出路径路由。在工作进程与 HTTP 处理程序中,请优先使用S或F,以便由你自己掌控响应——参见 /integrations/tcpdf-compat/production-usage/. - 严格模式并非生产环境设置。 请将其保留给 CI/审计作业使用。在生产环境的渲染路径中抛出异常,比让参数无声地降级更糟。
- 常量管理。 请在首次构造适配器之前定义
PDF_*/K_*常量。这两个强化标志(K_TCPDF_CALLS_IN_HTML、K_TCPDF_THROW_EXCEPTION_ERROR)无法放宽;请勿尝试这么做。 - 随机所有者密码。 如果你依赖确定性的所有者密码,请明确设置它。否则每份文档都会生成一组强随机密码,且无法恢复。
威胁模型注意事项
标题为“威胁模型注意事项”的章节- 对于图像方法,在执行任何文件系统读取之前,流包装器路径就会被拒绝。图像类型检测(
TcpdfImages::getImageFileType)会将任何scheme://路径——phar://、php://以及其他 PHP 流包装器——视为包装器并跳过file_get_contents/getimagesize探测,回退为仅根据扩展名推断。这在 PHP 7.4 向后移植目标上封闭了一个 phar 元数据反序列化向量;包装器路径嵌入本身则会被引擎拒绝。 - 除引擎已做的处理外,本适配器不会额外验证或清理传给图像或输出方法的文件路径。请在应用程序边界处,将调用方提供的路径与 URL 视为不受信任。
- 传入 HTML 方法的 HTML 由引擎渲染,而不是由 TCPDF 的 HTML 解析器处理。旧版的 PHP 执行汇点已被封闭,但仍应将调用方提供的 HTML 视为不受信任的输入。
- 加密依靠标准处理器保护文档静态存储时的机密性。它无法取代你应用程序中的传输安全或访问控制。
另请参阅
标题为“另请参阅”的章节- /integrations/tcpdf-compat/method-coverage/ ——
SetProtection()、setSignature()的确切行为 - /integrations/tcpdf-compat/configuration/ ——两个强化、不可配置的标志
- /integrations/tcpdf-compat/production-usage/ ——工作进程、缓冲区、失败处理
docs/TCPDF_COVERAGE.md——权威的覆盖范围矩阵- 软件包
NOTICE——独立实现声明