
pdfbox 数字签名默认为认证签名,会禁止后续编辑;若需允许用户修改文本等内容,必须使用“批准签名”(approval signature)并配合文档权限设置,但需注意 adobe acrobat 等主流阅读器实际仍可能限制编辑——关键在于签名类型、mdp 权限级别及增量保存的协同配置。
pdfbox 数字签名默认为认证签名,会禁止后续编辑;若需允许用户修改文本等内容,必须使用“批准签名”(approval signature)并配合文档权限设置,但需注意 adobe acrobat 等主流阅读器实际仍可能限制编辑——关键在于签名类型、mdp 权限级别及增量保存的协同配置。
在 Apache PDFBox 中,签名行为本质上分为两类:认证签名(Certification Signature) 和 批准签名(Approval Signature)。二者核心区别在于:认证签名用于锁定文档完整性(通常由文档作者添加,可设定不同级别的修改限制),而批准签名仅用于验证签署者身份与签署意图,本身不施加任何编辑限制——但前提是它不作为首个签名存在,且文档未被预先认证。
然而,您的代码存在一个关键误区:当前调用 document.addSignature(signature, this) 添加的是首个签名,PDFBox 默认将其视为认证签名(即使未显式设置 MDP),且 Adobe Acrobat 会据此启用严格的修改保护策略(等效于 MDP=3,即“禁止所有更改”)。这正是您遇到“签名后无法编辑”的根本原因。
要实现“签名后仍允许用户编辑文本”的目标,需满足以下条件:
确保签名是批准签名而非认证签名:
首个签名必须明确声明为批准签名,并避免触发认证逻辑。PDFBox 中,可通过设置 PDSignature 的 setCertificationLevel() 为 0(即 CERTIFIED_NO_CHANGES_ALLOWED 不适用),但更可靠的方式是不在首个签名中设置任何 MDP 权限,并确保不调用 setCertificationLevel()。使用增量保存(saveIncremental)并避免重写原始流:
您已正确使用 document.saveIncremental(output),这是必需的——它将签名追加至文件末尾,保留原始内容可编辑性。切勿使用 document.save(output),否则会重写整个 PDF,破坏签名结构。理解 Adobe 的实际行为限制:
尽管 PDF 规范允许批准签名后进行表单填写、注释添加等操作,但 Adobe Acrobat(v10+)默认将首个签名解释为认证签名,并强制执行 MDP=3 级别限制。因此,若需兼容 Acrobat,唯一可靠方案是:先创建一个空的认证签名(MDP=1 或 MDP=2),再添加批准签名。例如:
// 第一步:添加最低权限认证签名(仅允许表单填写和注释)
PDSignature certSig = new PDSignature();
certSig.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
certSig.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
certSig.setCertificationLevel(PDSignature.CERTIFIED_FORMS_FILLING); // MDP=1
document.addSignature(certSig, signer);
// 第二步:保存认证签名(增量)
try (FileOutputStream fos = new FileOutputStream("certified.pdf")) {
document.saveIncremental(fos);
}
// 第三步:重新加载并添加批准签名(不设 MDP)
PDDocument docWithCert = PDDocument.load(new File("certified.pdf"));
PDSignature approvalSig = new PDSignature();
approvalSig.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
approvalSig.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);
approvalSig.setName("Approver Name");
docWithCert.addSignature(approvalSig, signer); // 此处 signer 实现 Signer 接口
try (FileOutputStream fos = new FileOutputStream("approved.pdf")) {
docWithCert.saveIncremental(fos); // 再次增量保存
}⚠️ 注意事项:
- PDSignature.CERTIFIED_FORMS_FILLING(MDP=1)允许表单字段填写与注释;CERTIFIED_FORMS_FILLING_AND_ANNOTATIONS(MDP=2)额外允许注释修改;两者均不允许直接编辑页面文本或图形。真正的“编辑文本”需依赖 PDF 编辑器能力,而 Acrobat 仍可能阻止此类操作。
- 所有签名必须使用 saveIncremental(),且签名过程不可中断或重写原始字节流。
- 测试时请使用 Adobe Acrobat Reader DC(而非浏览器内置 PDF 查看器)验证编辑行为,因其最严格遵循 PDF 规范。
总结:PDFBox 支持创建批准签名,但“允许自由编辑文本”受限于 PDF 规范设计与 Acrobat 实现策略。务实做法是:以 MDP=1/2 认证签名建立基础权限框架,再叠加批准签名增强可信度;同时向用户明确说明——签名后仅支持表单填写与注释,全文本编辑需依赖专业 PDF 编辑工具,且将导致签名失效。


















