In Itext 7, how to sign a pdf with 2 steps?

北城以北 提交于 2019-11-29 16:48:45

why is the result of this step invalid

Because you essentially discovered a bug... ;)

Your sample input file has one feature which triggers the bug: It is compressed using object streams.

When iText manipulates such a file, it also tries to put as many objects as possible into object streams. Unfortunately it also does so with the signature dictionary. This is unfortunate because after writing the whole file it tries to enter some information (which are not available before) into this dictionary which damages the compressed object stream.


What you can do...

You can either

  • wait for iText development to fix this issue - I assume this won't take too long but probably you don't have the time to wait; or
  • convert the file to sign into a form which does not use object streams - this can be done using iText itself but probably you cannot accept the file growth this means, or probably the files already are signed which forbids any such transformation; or
  • patch iText 7 to force the signature dictionary not to be added to an object stream - it is a trivial patch but you probably don't want to used patched libraries.

The patch mentioned above indeed is trivial, the method PdfSigner.preClose(Map<PdfName, Integer>) contains this code:

if (certificationLevel > 0) {
    // add DocMDP entry to root
    PdfDictionary docmdp = new PdfDictionary();
    docmdp.put(PdfName.DocMDP, cryptoDictionary.getPdfObject());
    document.getCatalog().put(PdfName.Perms, docmdp); // TODO: setModified?
}

document.close();

The cryptoDictionary.getPdfObject()) is the signature dictionary I mentioned above. During document.close() it is added to an object stream unless it has been written to the output before. Thus, you simply have to add a call to flush that object right before that close call and by parameter make clear that it shall not be added to an object stream:

cryptoDictionary.getPdfObject().flush(false);

With that patch in place, the PDFs your code returns are not damaged as above anymore.


As an aside, iText 5 does contain a similar line in the corresponding PdfSignatureAppearance.preClose(HashMap<PdfName, Integer>) right above the if block corresponding to the if block above. It seems to have been lost during refactoring to iText 7.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!