安全性总览
TCPDF-Next 以安全优先的哲学进行设计。作为一套处理数字签名、加密与机密文件的库,安全不是事后补强,而是核心架构原则。
安全优先设计
每一个组件在设计时都将安全纳入考量:
1. 全面淘汰过时密码学
TCPDF-Next 在编译期与运行期均拒绝所有已弃用和不安全的算法:
- RC4 — 禁止使用(已知多种攻击手法的破损加密法)
- MD5 — 禁止使用(自 2004 年以来已展示碰撞攻击)
- SHA-1 — 拒绝用于所有签名操作(自 2017 年以来已展示碰撞攻击)
- RSA 密钥 < 2048 位 — 拒绝(1024 位密钥已可被分解)
- DES / 3DES — 未实现
2. 内存安全
- 所有机密数据(私钥、密码、解密内容)存储于
SensitiveString对象中,不再使用时自动从内存归零 - 在可用的情况下使用 PHP 的
sodium_memzero()进行安全的内存清除 - 含有机密数据的临时文件会通过覆写方式安全删除
3. 输入验证
- 所有 PDF 输入在处理前均经过严格验证
- 畸形的 PDF 结构会被拒绝,而非以「尽力解析」方式处理
- 所有大小计算均包含整数溢出检查
- 嵌入式文件处理具备路径遍历防护
4. 常数时间操作
- HMAC 验证使用常数时间比较(
hash_equals()) - 密码验证使用常数时间比较
- 密码学操作不会产生基于计时的信息泄漏
加密
TCPDF-Next 支持使用 AES-256 的 PDF 2.0 加密:
php
use YeeeFang\TcpdfNext\Encryption\EncryptionAlgorithm;
use YeeeFang\TcpdfNext\Encryption\Permissions;
$pdf->setEncryption()
->setAlgorithm(EncryptionAlgorithm::AES256)
->setUserPassword('reader-password')
->setOwnerPassword('admin-password')
->setPermissions(
Permissions::PRINT_HIGH_QUALITY
| Permissions::COPY
| Permissions::ACCESSIBILITY
)
->apply();加密功能
| 功能 | 说明 |
|---|---|
| AES-256-CBC | 依据 PDF 2.0(Revision 6)的默认加密 |
| 公钥加密 | 针对多个收件者的证书式加密 |
| 细粒度权限 | 控制打印、复制、修改、注解、填写表单、提取、组装 |
| 元数据加密 | 文档元数据可选择性加密 |
WARNING
加密保护的是文件机密性,但无法保证完整性或不可否认性。如需完整性与不可否认性,请同时搭配使用数字签名与加密。
数字签名
TCPDF-Next 完整实现了 PAdES 基准配置文件(ETSI EN 319 142-1)的数字签名:
| 等级 | 说明 | 验证有效期 |
|---|---|---|
| PAdES B-B | 基础 CMS 签名 | 证书有效期(约 1-3 年) |
| PAdES B-T | + RFC 3161 时间戳 | TSA 证书有效期(约 10-15 年) |
| PAdES B-LT | + DSS 含 OCSP/CRL 数据 | 算法安全寿命(约 15-30 年) |
| PAdES B-LTA | + 归档时间戳 | 无限期(搭配重新戳记) |
详细信息请参阅 PAdES B-LTA 签名。
安全架构
┌─────────────────────────────────────────────────────┐
│ 应用程序层 │
│ (您使用 TCPDF-Next API 的代码) │
├─────────────────────────────────────────────────────┤
│ 验证层 │
│ • 输入净化 • PDF 结构验证 │
│ • 参数验证 • 证书链检查 │
├─────────────────────────────────────────────────────┤
│ 密码学层 │
│ • AES-256 加密 • CMS 签名构建 │
│ • RSA/ECDSA/EdDSA • 哈希计算 │
│ • HMAC 验证 • 密钥派生 │
├─────────────────────────────────────────────────────┤
│ 核心 PDF 层 │
│ • 对象序列化 • 流压缩 │
│ • 交叉引用生成 • 增量更新 │
├─────────────────────────────────────────────────────┤
│ PHP 运行环境与扩展 │
│ • OpenSSL • Sodium • mbstring • zlib │
└─────────────────────────────────────────────────────┘依赖安全
TCPDF-Next 将外部依赖降至最低,以缩小攻击面:
- 零运行时依赖 — 核心 PDF 生成不依赖任何第三方 Composer 包
- OpenSSL 扩展 — 密码学操作所需(使用 PHP 内置绑定)
- Sodium 扩展 — 可选,用于安全内存清除及 Ed25519/Ed448(PHP 8.5+ 已内置)
- zlib 扩展 — 流压缩所需(PHP 已内置)
- mbstring 扩展 — Unicode 文字处理所需(PHP 已内置)
TIP
TCPDF-Next 刻意避免依赖外部 PHP 密码学库。所有密码学操作均使用 PHP 内置的 OpenSSL 与 Sodium 扩展,它们是经过充分审计之 C 库的薄封装。
负责任披露政策
我们严肃对待安全漏洞。若您发现 TCPDF-Next 的安全问题,请依照以下负责任披露流程进行:
报告漏洞
- 请勿在公开的 GitHub Issue 中报告安全漏洞
- 电子邮件:[email protected](PGP 密钥如下)
- 请包含:
- 漏洞描述
- 重现步骤
- 潜在影响评估
- 建议修复方式(如有)
响应时程
| 阶段 | 时程 |
|---|---|
| 确认收到 | 24 小时内 |
| 初步评估 | 72 小时内 |
| 修复开发 | 14 天内(重大)、30 天内(高) |
| 公开披露 | 报告后 90 天,或修复发布时 |
安全配置
建议的 php.ini 配置
ini
; 确保加载 OpenSSL
extension=openssl
; 确保加载 Sodium(PHP 8.5+ 已内置)
extension=sodium
; 停用 PDF 生成不需要的危险函数
disable_functions = exec,passthru,shell_exec,system,proc_open,popen
; 为 PDF 生成设置合理的内存限制
memory_limit = 256M
; 若接受 PDF 上传,设置合理的文件大小限制
upload_max_filesize = 50M
post_max_size = 50MTCPDF-Next 安全配置
php
use YeeeFang\TcpdfNext\Security\SecurityConfig;
SecurityConfig::global()
->setMinRsaKeySize(2048)
->setMinEcKeySize(256)
->setRejectSha1(true)
->setRejectRc4(true)
->setSecureMemoryWipe(true)
->setStrictPdfParsing(true)
->setMaxPdfFileSize(100 * 1024 * 1024) // 100 MB
->setMaxEmbeddedFileSize(50 * 1024 * 1024); // 50 MB安全文档
- 安全审计报告 — 第三方审计发现与修复
- TCPDF CVE 修复对照 — 已知 TCPDF 漏洞的处置方式
- 威胁模型 — PDF 签名攻击向量与缓解措施
- 安全最佳实践 — 安全部署建议