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

Trying to sign a pdf document with java. Why is the signature invalid in the PDF files?

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

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

但是,我想使用同一个文件,这意味着我不再假装复制 PDF。我要抢文档,签名,覆盖原来的

因为我知道让 FileInputStream 和 FileOutputStream 指向同一个文件不是一个好主意,所以我只是尝试使用 File class.

我尝试了以下方法:

       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 文件确实按预期被覆盖,但是,当我打开文件时,签名不再有效。我读了这些问题……它与这些问题中的任何一个有关吗?我该怎么做才能解决这个问题?

感谢您的帮助!

1.8.* saveIncremental(filename) 在 PDFBox 1.8.16 之前一直存在问题。 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 调用。