“AT least one signature is invalid” error message after removing signature from pdf using itext

给你一囗甜甜゛ 提交于 2020-03-27 02:40:34

问题


I have a digitally signed pdf with multiple signatures. Now I want to remove only one of the signatures. I am using itext for the same. The code is as follows:

PdfReader reader = new PdfReader(src_path);

PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest_path));


         {
                AcroFields.Item item =        stamper.getAcroFields().getFieldItem(fieldname);

                ClearSignatureDictionary(item.getMerged(0));
                ClearSignatureDictionary(item.getWidget(0));
                ClearSignatureDictionary(item.getValue(0));
            }
        }

 private static void ClearSignatureDictionary(PdfDictionary dic)
  {
    dic.remove(PdfName.AP);
    dic.remove(PdfName.AS);
    dic.remove(PdfName.V);
    dic.remove(PdfName.DV);
    dic.remove(PdfName.SV);
    dic.remove(PdfName.FF);
    dic.put(PdfName.F, new PdfNumber(4));
 }

But when I open the document with the removed signature, it gives me the following error on Acrobat reader "At least one of the signatures is invalid"


回答1:


You can not remove keys from a dictionary in a signed document, and expect the signatures to remain valid. You can only remove the last signature that was added. If a document was signed by multiple people, and you want to remove the first signature, all subsequent signatures will be broken.

This image explains why:

This image shows that every new digital signature keeps the original bytes intact. With every new signature new bytes are added. Rev1 represents the bytes of a document that has 1 digital signature. Rev2 represents the bytes of a document that has 2 digital signatures. The second digital signatures signs Rev1 completely. If you'd remove the first signature, the second signature would become invalid.

A digital signature is a special type of form field. With iText, you can get the names of the signature form fields of a PDF like this:

PdfReader reader = new PdfReader(path);
AcroFields fields = reader.getAcroFields();
ArrayList<String> names = fields.getSignatureNames();

You can only remove the signature that covers the whole document, for instance, if we have "sig1", "sig2", and "sig3" (added in that order), only fields.signatureCoversWholeDocument("sig3") will return true.

You can get the total number of revisions like this: fields.getTotalRevisions() and a specific revision like this: fields.getRevision("sig1") (provided that there's a signature field named "sig1").

Suppose that the image represents your document, and you have to remove 1 signature, then you can only remove the third signature by removing all the bytes that were added in revision 3 (Rev3). With iText, that means going back to revision 2 (Rev2). That revision was signed using the signature field sig2. You can extract this revision like this:

FileOutputStream os = new FileOutputStream("revision2.pdf");
byte bb[] = new byte[1028];
InputStream ip = fields.extractRevision("sig2");
int n = 0;
while ((n = ip.read(bb)) > 0)
    os.write(bb, 0, n);
os.close();
ip.close();

The file revision2.pdf will be the file signed by "sig1" and "sig2" without the bytes that were added when creating "sig3".



来源:https://stackoverflow.com/questions/39919205/at-least-one-signature-is-invalid-error-message-after-removing-signature-from

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