1
votes

I had some pdf multi signing workflow requirement. In this pdf will get signed multiple times without changes to the document say 2 or more people can sign same document. I am trying to add the signatures in pdf twice but after signing pdf second time first signature get invalid. I have used PDFBox Java api for pdf signature creation.

PDF Creation steps:

  1. Created pdf by adding empty signature fields names: [email protected] and [email protected] using original hello.pdf out put file name hello_tag.pdf run program >TagPDFSignatureFields.java
  2. First time signing by fetching signature field [email protected] from hello_tag.pdf file, out file name is hello_signed.pdf run program >SignAndIdentifySignatureFields.java
  3. Second time signing by fetching signature field [email protected] from hello_signed.pdf file, out file name is hello_singed2.pdf run program >Sign2.java

In 2nd step pdf gets signed properly but after 3rd step, 2nd step signed version gets invalided and 3rd step signature shows okay in acrobat reader.

Please find link Java source code and pdf sample for reference. Google drive link pdf_multi_signs_pdfbox_java

Any help would be appreciated.

1
First error: You use period characters ('.') in the signature field partial names. This is invalid, partial names must not contain period characters.mkl

1 Answers

3
votes

In short there are a number of issues in your code. The issue causing Adobe Reader to mark your first signature as invalid after adding a second signature actually already is in your preparation step TagPDFSignatureFields where you create an invalid duplicate pages tree entry. The other issues should also be fixed, even though Adobe Reader currently does not complain.

The issues in detail...

Duplicate Page Entry

In TagPDFSignatureFields your method addEmptySignField starts like this:

private void addEmptySignField(String[] args) throws Exception, IOException {
    // Create a new document with an empty page.
    try (PDDocument document = PDDocument.load(new File(args[0]));)
    {
        PDPage page = document.getPage(0);
        document.addPage(page);

Here you retrieve the first page of document and immediately add that page to document again. This causes the pages root tree node in your file hello_tag.pdf to look like this:

2 0 obj
<<
/Type /Pages
/Count 2
/Kids [6 0 R 6 0 R]
>>
endobj 

I.e. the pages tree contains the same page object twice which Adobe Reader does not accept but repairs under the hood. For the signed documents Adobe Reader warns about this in a vague way:

Warning

And in current versions (e.g. 2020.013.20066) Adobe Reader in the twice signed file even marks the first signature as broken. In earlier versions (e.g. 2019.012.20040) it did not do so. Probably this is an effect of the hardening of the validation code after the Shadow Attacks had been published.

As an aside: If you have a situation in which manipulating a signed document (form fill-ins, signing again, ...) breaks the old signatures, always also check whether the original document might already have issues. The check whether changes applied to a signed document are allowed, are quite sensitive to errors which otherwise are fixed under the hood and, therefore, not visible.

Invalid Partial Field Names

You use email addresses as field names, [email protected] and [email protected] in case of your example:

signatureField.setPartialName("[email protected]");
...
signatureField1.setPartialName("[email protected]");

(TagPDFSignatureFields method addEmptySignField)

These partial field names are invalid, partial field names must not contain period characters ('.').

PDFBox in future versions will try to prevent this, see PDFBOX-5028.

Setting the Default Resources And Default Appearances Upon Signing

During signing you set the default resources and default appearance of the AcroForm dictionary:

acroForm.setDefaultResources(resources);
...
acroForm.setDefaultAppearance(defaultAppearanceString);

(SignAndIdentifySignatureFields and Sign2 method addEmptySignField)

By itself this is not a bad thing but beware, if you do this to a previously signed file which already has such entries and you set them to different values than before, this can invalidate the former signature, see the issue answered here.

Setting PDF Version Without Need

You try to change the claimed PDF version of the document:

document.setVersion(1.0f);

(SignAndIdentifySignatureFields method addEmptySignField)

document.setVersion(2.0f);

(Sign2 method addEmptySignField)

The first instruction is ignored as the document itself already requires a version of at least 1.5, but the second instruction indeed sets the document PDF version to 2.0 which may cause issues with older viewers.

...

There quite likely are more issues. I merely first spotted these issues before I recognized that already fixing the only first one, the Duplicate Page Entry, sufficed to heal the first signature...