当前位置: 首页 > 知识库问答 >
问题:

PDFBox 1.8.10:填充和签名PDF生成无效签名

戚森
2023-03-14

我在PDF文档中(以编程方式)填写一个表单(AcroPdf),然后在文档上签名。我从doc.pdf开始,使用pdfbox的setfields.java示例创建doc_filler.pdf。然后我对doc_fill.pdf进行签名,创建doc?filled_signer.pdf,使用一些代码,基于签名示例并在Acrobat Reader中打开pdf。输入的字段数据是可见的,并且签名面板告诉我

“此签名中包含的格式或信息有错误(签名字节数组无效)”

>

  • 单独应用的签名代码(即直接创建一些doc_signer.pdf)将创建有效签名
  • 添加到现有签名字段的“不可见签名”、可见签名和可见签名存在问题。
  • 如果我不填写表单,而是打开表单并保存它,甚至会出现问题,即:

    PDDocument doc = PDDocument.load(new File("doc.pdf"));
    doc.save(new File("doc_filled.pdf"));
    doc.close();
    

    足以破坏随后应用的签名代码。

    另一方面,如果我使用相同的doc.pdf,在Adobe中手动输入字段的值,签名代码将生成有效的签名。

    @MKL让我提供的文件,我说的是(我目前信誉不够,把所有文件都作为链接贴出来,不便之处抱歉):

      null

    最后一个是通过一次性签名和填写文档创建的,使用

        doc.saveIncremental(); 
    

    正如我在评论中所写的,一些

        setNeedToBeUpdate(true);
    

    但似乎不见了。参考@mkl的第二条评论,我发现了这样的问题:在使用PDFBOX生成的PDF中,保存的文本字段值没有正确显示,这也包括了一些输入的文本没有显示。我第一次尝试,申请

        setBoolean(COSName.getPDFName("NeedAppearances"), true); 
    

    更新:故事继续如下:pdfbox1.8.10:填写并签署文档,再次填写失败

  • 共有1个答案

    孙嘉悦
    2023-03-14

    OP原来问题的原因,即用PDFBox加载他的PDF(用于表单填写)后保存后,这个新PDF无法使用PDFBox签名码成功签名,在本答案中已经详细说明了,简而言之:

    >

  • 定期保存文档时,PDFBox使用对照表进行保存。

    • 如果要定期保存的文档是从带有交叉引用流的PDF加载的,则交叉引用流字典的所有条目都保存在拖车字典中。
      null

    因此,在OP的原始PDFdoc.PDF具有交叉引用流的情况下:

    >

  • 在加载和表单填写后,定期保存文档,即使用对照表,但所有以前的对照流条目,其中包括类型,都复制到拖车中。(doc_fill.pdf)

    在加载这个保存的PDF和用于签名的对照表之后,使用增量更新再次保存它。PDFBox假定(由于Type trailer条目)现有文件有一个交叉引用流,因此在增量更新结束时也使用交叉引用流。(doc_filled_signer.pdf)

    因此,最终,填写后签名的PDF有两个版本,内部版本有一个交叉引用表,外部版本有一个交叉引用流。

    由于这是无效的,Adobe Reader在加载PDF时会在其内部文档表示中修复这一点。修复会更改文档字节。这样,Adobe Reader眼中的签名就被打破了。

    大多数其他签名验证器不会尝试这样的修复,而是按原样检查文档的签名。则它们将成功验证签名。

    >

  • a:加载用于表单填写的PDF后,在定期保存之前,从拖车中删除类型条目。如果将签名应用于此文件,PDFBox将假定为一个交叉引用表(因为误导的类型条目不存在。因此,签名增量更新将是有效的)。

    B:使用增量更新来保存表单填写更改,可以在单独的运行中保存,也可以在与签名相同的运行中保存。这也会导致有效的增量更新。

    一般来说,我会建议后一个选项,因为如果PDFBox保存例程彼此兼容,前一个选项可能会中断。

    在目前的情况下,OP尝试了后一个选项(doc_filled_and_signer.pdf):

    目前,文本框的内容仅在选中文本框时才可见(使用Acrobat reader和预览相同的行为)。我标记PDField、它的所有父级、AcroForm、目录以及显示它的页面。

    他将更改的字段标记为已更新,但未标记相关的外观流,后者在设置表单字段值时由PDFBox自动生成。

    因此,OP还必须标记新的正常外观流(表单字段字典包含一个条目AP,该条目引用了一个字典,其中N引用了正常外观流)。或者(如果查找更改或添加的条目变得过于繁琐),他可能会尝试其他选项。

  •  类似资料:
    • 问题内容: 我在PDF文档中(以编程方式)填写了表格(AcroPdf),然后在文档上签名。我从doc.pdf开始,使用PDFBox的setFields.java示例创建doc_filled.pdf。然后,我根据签名示例使用一些代码对doc_filled.pdf进行签名,以创建doc?filled_signed.pdf,然后在Acrobat Reader中打开pdf。输入的字段数据可见,签名面板告诉

    • 我有一个问题与数字签名PDF文件已标记为PDF/A-3A兼容。使用PDFBox(最新版本,2.0.24)最终在Adobe Acrobat中获得无效签名,而使用iText7(最新版本)获得有效签名。目标是获得符合PAdES LTV的签名。 我的流程如下(使用PDFBox和iText7): 打开PDF,创建用于签名的散列(要签名的数据) 我呼叫第三方服务以取回数字签名 在服务响应中,我还获得了OCSP

    • 当我使用带电子令牌的IText对PDF进行签名时,签名的PDF在Acrobat Adobe Reader中显示“至少一个签名无效”。我正在使用有效的电子代币。以下是签署Pdf的代码。

    • 作为我对客户机/服务器pdf签名研究的一部分,我测试了itext pdf延迟签名示例。不幸的是,我得到的合并空签名pdf和哈希值的pdf ie输出显示无效签名。 下面是我的代码片段 我正在使用pkcss11 usb令牌进行签名

    • PDF下载示例:https://drive.google.com/file/d/12wv1Pb7gh4vCKOGhX4cZ3aOrLSiOo4If/view?usp=sharing 因此,当PDF在A.Reader(连续版本)中打开时,它表示证书无效,因为对该文档所做的更改导致签名无效。 但我看不出有什么变化。我们自己的应用程序只添加了一个签名(证书),为数千个其他PDF添加了正确的签名。未执行其

    • 我对iTextSharp有意见。我有一个带有表单字段的文档,并且我已经为签名生成了字段。当第一个人在文件上签字时,它就会正常工作。Adobe Reader显示有效签名。当我让第二个人在文档上签名时,Adobe Reader显示签名1现在是“未知签名”,签名无效。Adobe reader显示: 此签名中包含的格式或信息有错误(支持信息:SigDict/Contents非法数据)