PDFBox - открытие и сохранение подписанного PDF делает мою подпись недействительной

Я пытаюсь научиться использовать Apache pdfBox для работы с документами с цифровой подписью для работы. Во время тестирования я создал полностью пустой документ PDF.

Затем я подписал документ через Adobe Reader, используя функцию подписи с сертификатом.

Я пытался открыть, сохранить и закрыть подписанный файл с pdfBox без каких-либо изменений. Однако, как только я открываю файл в Adobe, файлы больше не действительны.

Adobe сообщает мне: «Есть ошибки в форматировании или информации, содержащейся в этой подписи (информация о поддержке: SigDict / Contents недопустимые данные)»

Поскольку я не изменял содержимое файла, интуитивно не должно было быть никаких проблем, и подпись должна оставаться действительной, однако это не тот случай, и я не знаю, какие есть решения (поиск в Google не дал результатов).

Как я создаю документ:

@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();

}

Когда я добавляю аннотацию, используя ее для не подписанного документа, аннотация добавляется и становится видимой. Однако при использовании его в подписанном документе аннотация не появляется.

Я открыл файл pdf в notepad ++ и обнаружил, что аннотация, кажется, была добавлена ​​с тех пор, как я нашел это, а также остальную часть кода, относящегося к аннотации:

<<
/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. Возможно, это больше связано с потоками внешнего вида, чем с самой аннотацией?

Ответы на вопрос(2)

Ваш ответ на вопрос