“至少一个签名无效”。使用itext从pdf中删除签名后出现错误消息 [英] "AT least one signature is invalid" error message after removing signature from pdf using itext
问题描述
我有一个带有多个签名的数字签名pdf。现在我想只删除其中一个签名。我正在使用itext。代码如下:
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));
}
但是当我用删除的签名打开文档时,它给了我以下内容Acrobat reader上的错误
至少有一个签名无效
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"
推荐答案
您无法从中删除密钥签名文档中的字典,并期望签名保持有效。您只能删除添加的最后一个签名。如果文档由多人签名,并且您想要删除第一个签名,则所有后续签名都将被破坏。
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.
此图片解释了原因:
此图像显示每个新的数字签名都保持原始字节的完整性。每个新签名都会添加新字节。 Rev1表示具有1个数字签名的文档的字节。 Rev2表示具有2个数字签名的文档的字节。第二个数字签名完全标志着Rev1。如果您删除第一个签名,则第二个签名将无效。
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.
数字签名是一种特殊类型的表单字段。使用iText,您可以获得PDF的签名表单字段的名称,如下所示:
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();
您只能删除涵盖整个文档的签名,例如,如果我们有sig1
,sig2
,sig3
(已添加按此顺序),只有 fields.signatureCoversWholeDocument(sig3)
将返回true。
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.
你可以得到像这样的修订总数: fields.getTotalRevisions()
以及这样的特定修订: fields.getRevision(sig1)
(假设有一个名为的签名字段sig1
)。
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"
).
假设图像代表你的文档,您必须删除1个签名,然后您只能通过删除在修订版3(Rev3)中添加的所有字节来删除第三个签名。使用iText,这意味着返回修订版2(Rev2)。该修订是使用签名字段 sig2
签署的。
您可以像这样提取此修订:
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();
文件 revision2.pdf
将是文件由sig1
和sig2
签名,没有创建时添加的字节sig3
。
The file revision2.pdf
will be the file signed by "sig1"
and "sig2"
without the bytes that were added when creating "sig3"
.
这篇关于“至少一个签名无效”。使用itext从pdf中删除签名后出现错误消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!