iText7 PDF SignDeferred异常:签名有效但存在未签名变更
问题分析与解决方案
核心原因
你在已完成签名的PDF文档上追加修改签名域的可视化外观,这属于签名生成后的未授权变更(即使认证级别允许修改,这些修改也没有被签名流程覆盖),所以Adobe Reader会检测到“签名全部有效但存在未签名变更”。
正确解决方案
方案1:签名前预先创建签名域的可视化外观(推荐)
不要在签名完成后再修改签名域,而是在调用SignedDeferred签名前,就创建好签名域并配置好外观模板,让签名操作直接覆盖包含外观的文档内容。示例代码框架:
// 加载源文档,启用追加模式 PdfReader reader = new PdfReader(sourcePdfPath); PdfWriter writer = new PdfWriter(signedPdfPath); PdfDocument pdfDoc = new PdfDocument(reader, writer, new StampingProperties().UseAppendMode()); // 获取或创建AcroForm PdfAcroForm acroForm = PdfAcroForm.GetAcroForm(pdfDoc, true); // 创建签名域 PdfSignatureFormField signatureField = PdfFormField.CreateSignature(pdfDoc); signatureField.SetFieldName("Signature"); // 配置签名域位置与初始外观 foreach (PdfWidgetAnnotation widget in signatureField.GetWidgets()) { widget.SetRectangle(new Rectangle(36, 348, 236, 428)); // 创建外观XObject PdfFormXObject formXObj = new PdfFormXObject(new Rectangle(200, 80)); Canvas canvas = new Canvas(formXObj, pdfDoc); canvas.SetFontSize(6); canvas.Add(new Paragraph().SetItalic().Add("Signed by:")); canvas.Add(new Paragraph().Add("[待签名后填充]")); canvas.Add(new Paragraph().SetItalic().Add("Date:")); canvas.Add(new Paragraph().Add("[待签名后填充]")); widget.SetNormalAppearance(formXObj.GetPdfObject()); } acroForm.AddField(signatureField); // 执行签名操作(MySigner.SignedDeferred) MySigner signer = new MySigner(reader, writer, new StampingProperties().UseAppendMode()); signer.SetFieldName("Signature"); // 其他签名参数配置(证书、哈希算法等) signer.SignExternalContainer(externalSignatureContainer, estimatedSize); pdfDoc.Close();
如果需要动态填充签名人、日期等数据,可以在签名容器的Sign方法中,获取签名域并更新外观内容。
方案2:签名后添加可视化并进行二次签名
如果必须在签名完成后添加可视化,需要对修改后的文档执行二次签名,让新签名覆盖这次变更:
- 先执行你原有的代码,完成可视化外观的添加;
- 对生成的
pathDestination2文档执行第二次签名操作,使用追加模式添加新的签名。
你尝试的方法无效原因说明
- 设置
CERTIFIED_FORM_FILLING_AND_ANNOTATIONS后Adobe不识别签名:大概率是签名流程中出现了格式错误(比如继承PdfSigner时破坏了签名结构),而非认证级别本身的问题; - 切换
SetModified属性:修改操作本身是在签名完成后进行的,无论是否标记修改,Adobe都会检测到签名后的内容变更,所以无法解决问题。
内容的提问来源于stack exchange,提问作者Evan Econo
相关产品推荐
相关产品推荐

