我要删除最后一个签名,其他签名也可以使用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的人将不再看到签名,因为相关对象将在交叉引用表。

尽管此“解决方案”在理论上可能有用,但极不可能是您想要的解决方案。但是,您的用例非常少见,我怀疑是否有技术方法可以实现它。正如我在评论中所解释的那样,工作流中的一个步骤应该已经导致第一个签名中断。

07-24 18:23
查看更多