尝试使用 java 签署 pdf 文档。为啥 PDF 文件中的签名无效?

Posted

技术标签:

【中文标题】尝试使用 java 签署 pdf 文档。为啥 PDF 文件中的签名无效?【英文标题】:Trying to sign a pdf document with java. Why is the signature invalid in the PDF files?尝试使用 java 签署 pdf 文档。为什么 PDF 文件中的签名无效? 【发布时间】:2018-10-29 13:39:03 【问题描述】:

我目前正在一个 Java 应用程序上处理 PDF,该应用程序对 PDF 文档进行了一些修改。

目前,这些 PDF 的签名工作正常,因为我正在使用 FileInputStream 和 FileOutputStream 等类。基本上,我从源文件夹中复制原始文档,然后将它们放在输出文件夹中。我正在使用带有 pdfbox 1.8.9 的 PDDocument 类

但是,我想使用相同的文件,这意味着我不再假装复制 PDF。我想获取文件,签名,然后覆盖原始文件。

因为我了解到让 FileInputStream 和 FileOutputStream 指向同一个文件不是一个好主意,所以我只是尝试使用 File 类。

我尝试了以下方法:

       File file = new File(locOriginal);    
                PDDocument doc = PDDocument.load(file); 
                PDSignature signature = new PDSignature();
                Overlay overlay = new Overlay();

//The signature itself. It has not been modified
            signature.setFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED); // default filter

       signature.setSubFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED);

                if (msg.getAreaNegocio().startsWith("A")) 
                    signature.setName(this.campoCertificadoAcquiring);
                    signature.setLocation(this.localCertificadoAcquiring);
                    signature.setReason(this.razaoCertificadoAcquiring);
                else 
                    signature.setName(this.campoCertificadoIssuing);
                    signature.setLocation(this.localCertificadoIssuing);
                    signature.setReason(this.razaoCertificadoIssuing);
                

                // register signature dictionary and sign interface
               doc.addSignature(signature,this);
              doc.saveIncremental(file.getAbsolutePath());

               doc.close();

我的 PDF 文件确实按预期被覆盖,但是当我打开文件时签名不再有效。我读了这些问题......它与这些问题中的任何一个有关吗?我能做些什么来解决这个问题?

PDFBox 1.8.10: Fill and Sign PDF produces invalid signatures

PDFBox - opening and saving a signed pdf invalidates my signature

感谢您的帮助!

【问题讨论】:

顺便说一句:signature.setFilter(PDSignature.SUBFILTER_ADBE_PKCS7_DETACHED) - 将过滤器设置为子过滤器名称没有意义。现在过滤器名称已经不再重要了,所以这可能不会导致失败,但设置它仍然是无稽之谈。 我没有开发代码。此代码是很久以前制作的,但感谢您启发我! :) 【参考方案1】:

在 PDFBox 1.8.16 之前,1.8.* saveIncremental(filename) 是错误的。这在PDFBOX-4312 中有所描述,但令人困惑,因为用户删除了他自己的大部分消息并遇到了多个其他问题。如果您坚持使用过时的版本(存在安全问题),请尝试使用此代码而不是调用saveIncremental(filename)

//BEWARE: do not "optimize" this method by using buffered streams,
// because COSStandardOutputStream only allows seeking
// if a FileOutputStream is passed, see PDFBOX-4312.
FileInputStream fis = new FileInputStream(fileName);
byte[] ba = IOUtils.toByteArray(fis);
fis.close();
FileOutputStream fos = new FileOutputStream(fileName);
fos.write(ba);
fis = new FileInputStream(fileName);
saveIncremental(fis, fos);

不,我认为您链接的问题与您的问题无关。

顺便说一句,我不认为覆盖原始文件是个好主意。如果出现错误或断电,您将面临丢失文件的风险。

另见 mkl 的评论:setFilter() 通常用参数PDSignature.FILTER_ADOBE_PPKLITE 调用。

【讨论】:

“我不认为覆盖原始文件是个好主意” - +10! 我的想法完全正确,但我的客户要求这样做,因为要生成 10k 个文档,实际上我们会生成 50k 个文档,因为每次我们在文档中添加一些东西,比如背景图像、签名、复制,我们复制它们。我仍在探索覆盖同一个文件的可能性和影响,但他们希望这样。 如果无法使用,请分享原始文件和签名文件。

以上是关于尝试使用 java 签署 pdf 文档。为啥 PDF 文件中的签名无效?的主要内容,如果未能解决你的问题,请参考以下文章

JAVA 代码 使用PD4ML进行 html转换 PDF文档时,如果文档中存在 “~” 字符,则该字符转换的结果 不一致

签署文档时PDFBox 2.0.8问题

iText:在可见签名上显示签名细节

使用外部服务和iText签署PDF

为啥不在 java servlet 中创建 pdf 文档? [复制]

使用纯 JavaScript 签署 PDF