PDFBox-打开并保存签名的pdf会使我的签名无效

我正在尝试学习使用Apache的pdfBox处理经过数字签名的文档。在测试期间,我创建了一个完全空白的pdf文档。

然后,我使用带有证书的签名功能通过Adobe Reader对该文档进行了签名。

我尝试使用pdfBox打开,保存和关闭签名文件,没有进行任何修改。但是,一旦我在Adobe中打开文件,这些文件将不再有效。

Adobe告诉我:“此签名中包含的格式或信息有错误(支持信息:SigDict / Contents非法数据)”

由于我尚未修改文件的内容,因此从直观上讲应该没有任何问题,并且签名应该仍然有效,但是事实并非如此,我也不知道解决方案是什么(谷歌搜索没有结果)。

我如何创建文档:

@Test

public void createEmptyPDF() throws IOException {

String path = "path to file";

PDDocument document = new PDDocument();

PDPage page = new PDPage();

document.addPage(page);

document.save(path);

document.close();

}

然后,我用Adobe对其进行签名,并通过它进行传递:

 @Test

public void copySignedDocument() throws IOException {

String path = "path to file";

File file = new File(path);

PDDocument document = PDDocument.load(file);

document.save(file);

document.close();

//just opening and saving the file invalidates the signatures

}

我真不知道为什么这行不通。任何帮助将是巨大的!

编辑:

因此,我进行了一些深入研究,看来更新现有签名文档(添加注释或填写表格)尚未在PDFBox

2.0.1中实现,并且计划在2.1版中进行(但未指定发布日期)。这里和这里有更多信息。

但是,似乎可以使用IText在签名的文档上添加批注,而不会使用PDFStamper使签名无效,从这个问题开始

编辑2:代码以将图章添加到文档中并增量保存:

 @Test

public void stampSignedDocument() throws IOException {

File file = new File("path to file");

PDDocument document = PDDocument.load(file);

File image = new File("path to image to be added to annotation");

PDPage page = document.getPage(0);

List<PDAnnotation> annotations = page.getAnnotations();

PDImageXObject ximage = PDImageXObject.createFromFileByContent(image, document);

//stamp

PDAnnotationRubberStamp stamp = new PDAnnotationRubberStamp();

stamp.setName("testing rubber stamp");

stamp.setContents("this is a test");

stamp.setLocked(true);

stamp.setReadOnly(true);

stamp.setPrinted(true);

PDRectangle rectangle = createRectangle(100, 100, 100, 100, 100, 100);

PDFormXObject form = new PDFormXObject(document);

form.setResources(new PDResources());

form.setBBox(rectangle);

form.setFormType(1);

form.getResources().add(ximage);

PDAppearanceStream appearanceStream = new PDAppearanceStream(form.getCOSObject());

PDAppearanceDictionary appearance = new PDAppearanceDictionary(new COSDictionary());

appearance.setNormalAppearance(appearanceStream);

stamp.setAppearance(appearance);

stamp.setRectangle(rectangle);

PDPageContentStream stream = new PDPageContentStream(document, appearanceStream);

Matrix matrix = new Matrix(100, 0, 0, 100, 100, 100);

stream.drawImage(ximage, matrix);

stream.close();

//close and save

annotations.add(stamp);

page.getCOSObject().setNeedToBeUpdated(true);

OutputStream os = new FileOutputStream(file);

document.saveIncremental(os);

document.close();

os.close();

}

上面的代码不会使我的签名无效,但不会保存我添加的注释。

如建议的那样,我为添加的注释,页面和注释列表将NeedToBeUpdated标志设置为true(我希望我正确地完成了最后一个):

    stamp.getCOSObject().setNeedToBeUpdated(true);

COSArrayList<PDAnnotation> list = (COSArrayList<PDAnnotation>) annotations;

COSArrayList.converterToCOSArray(list).setNeedToBeUpdated(true);

page.getCOSObject().setNeedToBeUpdated(true);

document.getDocumentCatalog().getCOSObject().setNeedToBeUpdated(true);

注释仍未保存,因此我显然缺少了一些内容。

编辑3:

这是我当前添加注释的方法:

    @Test

public void stampSignedDocument() throws IOException {

File file = new File(

"E:/projects/eSign/g2digitalsignature/G2DigitalSignatureParent/G2DigitalSignatureTest/src/test/resources/pdfBoxTest/empty.pdf");

PDDocument document = PDDocument.load(file);

File image = new File(

"E:/projects/eSign/g2digitalsignature/G2DigitalSignatureParent/G2DigitalSignatureTest/src/test/resources/pdfBoxTest/digitalSign.png");

PDPage page = document.getPage(0);

List<PDAnnotation> annotations = page.getAnnotations();

PDImageXObject ximage = PDImageXObject.createFromFileByContent(image, document);

//stamp

PDAnnotationRubberStamp stamp = new PDAnnotationRubberStamp();

stamp.setName("testing rubber stamp");

stamp.setContents("this is a test");

stamp.setLocked(true);

stamp.setReadOnly(true);

stamp.setPrinted(true);

PDRectangle rectangle = createRectangle(100, 100, 100, 100, 100, 100);

PDFormXObject form = new PDFormXObject(document);

form.setResources(new PDResources());

form.setBBox(rectangle);

form.setFormType(1);

form.getResources().getCOSObject().setNeedToBeUpdated(true);

form.getResources().add(ximage);

PDAppearanceStream appearanceStream = new PDAppearanceStream(form.getCOSObject());

PDAppearanceDictionary appearance = new PDAppearanceDictionary(new COSDictionary());

appearance.setNormalAppearance(appearanceStream);

stamp.setAppearance(appearance);

stamp.setRectangle(rectangle);

PDPageContentStream stream = new PDPageContentStream(document, appearanceStream);

Matrix matrix = new Matrix(100, 0, 0, 100, 100, 100);

stream.drawImage(ximage, matrix);

stream.close();

//close and save

annotations.add(stamp);

appearanceStream.getCOSObject().setNeedToBeUpdated(true);

appearance.getCOSObject().setNeedToBeUpdated(true);

rectangle.getCOSArray().setNeedToBeUpdated(true);

stamp.getCOSObject().setNeedToBeUpdated(true);

form.getCOSObject().setNeedToBeUpdated(true);

COSArrayList<PDAnnotation> list = (COSArrayList<PDAnnotation>) annotations;

COSArrayList.converterToCOSArray(list).setNeedToBeUpdated(true);

document.getPages().getCOSObject().setNeedToBeUpdated(true);

page.getCOSObject().setNeedToBeUpdated(true);

document.getDocumentCatalog().getCOSObject().setNeedToBeUpdated(true);

OutputStream os = new FileOutputStream(file);

document.saveIncremental(os);

document.close();

os.close();

}

当我在未签名的文档上使用注释添加注释时,注释将被添加并且可见。但是,在已签名的文档上使用它时,不会出现注释。

我在notepad ++中打开了pdf文件,发现自从我发现该注释以及与该注释有关的其余代码以来,似乎已经添加了注释:

<<

/Type /Annot

/Subtype /Stamp

/Name /testing#20rubber#20stamp

/Contents (this is a test)

/F 196

/AP 29 0 R

/Rect [100.0 100.0 200.0 200.0]

>>

但是,当我在Adobe Reader中打开文档时,它不会出现。也许这与外观流更多地关系于注解本身?

回答:

问题是使用PDDocument.save()会创建一个新文档,从而使签名无效。

使用PDDocument.saveIncremental(…)不会使签名无效,但是不会更新文档的任何更改(例如注释或表单填充),仅用于保存签名。

PDFBox 2.0尚无法使用注释或表单填充来更新签名的PDF文档,但是一旦PDFBox 2.1推出,就应该可以进行更新。

有关此问题的信息:此处和此处

然而使用的iText的PDFStamper解决加上注解签署的文件,而不作为回答的签名无效的问题在这里。

以上是 PDFBox-打开并保存签名的pdf会使我的签名无效 的全部内容, 来源链接: utcz.com/qa/424250.html

回到顶部