我要删除最后一个签名,其他签名也可以使用adobe.reader verify_sign成功。
原始文件已签名并使用adobe.reader验证签名成功,但是当我执行此代码(不删除签名)时,目标文件使用adobe.reader验证签名失败。但是当我使用adobe.reader打开它们时,它们的内容显示正常。
我怀疑函数·PdfStamper·破坏了签名数据。我应该如何避免这个问题?
我使用itext和itextsharp(Java和C#),它们都是这个问题。 itex和itextsharp版本是5.5.10
我发现URL "AT least one signature is invalid" error message after removing signature from pdf using itext它已删除签名显示失败,但我没有删除签名,只有'new PdfStamper',目标文件使用adobe.reader验证签名失败。
谢谢〜
PdfReader re = new PdfReader(filePath);
PdfStamper pdfStamper = new PdfStamper(re, new FileStream(temfilePath, FileMode.Create));
//TODO temfilePath verify signature failed.
/*
* // not do this code
* //just remove the last signature.
* AcroFields acro = re.AcroFields;
* List<string> list = acro.GetSignatureNames();
* int i = 0;
* foreach (string s in list)
* {
* if (list.Count == i)
* {
* acro.ClearSignatureField(s); acro.RemoveField(s);
* }
* i++;
*
* }
*/
pdfStamper.Close();
re.Close();
最佳答案
签名被破坏是因为您将其破坏了。请阅读signatures documentation上的official website,您将找到Signatures代码示例。
public void extractFirstRevision(
String src, String dest, String sigName) throws IOException {
PdfReader reader = new PdfReader(src);
AcroFields af = reader.getAcroFields();
FileOutputStream os = new FileOutputStream(dest);
byte bb[] = new byte[1028];
InputStream ip = af.extractRevision(sigName);
int n = 0;
while ((n = ip.read(bb)) > 0)
os.write(bb, 0, n);
os.close();
ip.close();
}
这些是您需要的参数:
src
:已签名源文件的路径dest
:要创建的文件的路径sigName
:要为其提取修订的签名字段的名称更新1:
在评论中,您说要删除签名,而不是(签名的内容?),这就是我们通常所说的扁平化。在FlattenSignature示例中对此进行了解释:
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
stamper.setFormFlattening(true);
stamper.close();
现在,您将不再看到任何签名面板,但是将保留签名小部件。
更新2:
在另一个注释中,您明确要删除字段,并且此操作会破坏PDF中的签名之一。昨天,您发布了问题The saved file is not the same size as the original file,我通过参考常见问题解答进行了回答:Why do PDFs change when processing them?
由于我不知道的原因,您删除了该问题,但该常见问题解答中解释了导致当前问题的根本原因之一。请允许我从该答案中复制/粘贴:
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
这将创建一个新的PDF文件,其中的对象将被重新排序。您
可以通过将以下行更改为在附加模式下使用PdfStamper:
PdfStamper stamper = new PdfStamper(reader,
new FileOutputStream(dest), '\0', true);
现在,您正在创建PDF文件的增量更新。
您正在使用
PdfStamper
来重新组织PDF中的对象。这样做会破坏签名(请参阅答案的第一行)。如果您不想破坏签名,则需要进行增量更新。增量更新不会将任何内容更改为原始字节,从而使签名保持有效。我尚未对此进行测试,但是从理论上讲,您可以尝试在附加模式下删除第二个签名。这不会从文件中删除第二个签名(由于增量更新,第二个签名仍然存在),但是在PDF查看器中打开PDF的人将不再看到签名,因为相关对象将在交叉引用表。
尽管此“解决方案”在理论上可能有用,但极不可能是您想要的解决方案。但是,您的用例非常少见,我怀疑是否有技术方法可以实现它。正如我在评论中所解释的那样,工作流中的一个步骤应该已经导致第一个签名中断。