【问题标题】:How to merge PDFs without losing digital signature using Java (IText API)如何使用 Java (IText API) 在不丢失数字签名的情况下合并 PDF
【发布时间】:2018-10-22 10:37:00
【问题描述】:

我有一个经过数字签名的 pdf 文档,我想使用 java itext api 将此经过数字签名的 Pdf 附加到另一个普通 pdf,可以吗? 我试图将包含数字签名的 pdf 附加到另一个。我可以合并 pdf,但最终的 pdf 没有在输出 pdf 文件中保留数字签名。有可能吗?

【问题讨论】:

  • 数字签名的整个想法是验证PDF文件没有被修改。当然,如果您将不同的 PDF 附加到已签名的 PDF 中,这是一种修改。

标签: java pdf itext digital-signature


【解决方案1】:

正如其他人已经说过的那样,签名背后的想法(至少是想法的主要部分)是确保文档没有更改。另一方面,合并确实会改变文档。因此,合并会破坏签名。

不过,另一种方法是让另一个“普通”PDF 成为可移植集合(一种带有附件的特殊 PDF),并将签名的 PDF 附加到该集合。

从集合中打开已签名的 PDF 时,签名将与原始已签名 PDF 中的签名一样安然无恙。

创建可移植集合的示例代码

您可以在 iText 网站上找到可移植集合创建的示例:

public static final String DEST = "results/collections/portable_collection.pdf";
public static final String DATA = "resources/data/united_states.csv";
public static final String HELLO = "resources/pdfs/hello.pdf";
public static final String IMG = "resources/images/berlin2013.jpg";

public void createPdf(String dest) throws IOException, DocumentException {
    Document document = new Document();
    PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
    document.open();
    document.add(new Paragraph("Portable collection"));
    PdfCollection collection = new PdfCollection(PdfCollection.TILE);
    writer.setCollection(collection);
    PdfFileSpecification fileSpec = PdfFileSpecification.fileEmbedded(
            writer, DATA, "united_states.csv", null);
    writer.addFileAttachment("united_states.csv", fileSpec);
    fileSpec = PdfFileSpecification.fileEmbedded(
            writer, HELLO, "hello.pdf", null);
    writer.addFileAttachment("hello.pdf", fileSpec);
    fileSpec = PdfFileSpecification.fileEmbedded(
            writer, IMG, "berlin2013.jpg", null);
    writer.addFileAttachment("berlin2013.jpg", fileSpec);
    document.close();
}

(here 在网站上,here 在他们的 github 上)

该示例的运行结果是here。

(由于您使用的是 itext 标签而不是 itext7 标签,我假设您使用的是 iText 版本 5.5.x。)

【讨论】:

  • 它可以工作,但我无法按照我的要求订购附件。@mkl
  • This answer 展示了如何创建排序的便携式集合,但它适用于 iText 7。
  • 嘿,是否可以删除封面或者是否可以获得没有封面的pdf?如果我删除以下代码,则会出错。 document.add(new Paragraph("便携合集")); @mkl
  • “是否可以删除封面或者是否可以获得没有封面的 pdf?” - 您需要 PDF 中的一些内容,例如封面,但它不需要显示:您可以使用PdfCollection.setInitialDocument(String)将初始文档设置为显示。
  • “如何将文件存储在 ByteArrayOutputStream 中而不是存储在目标路径中” - 将 new FileOutputStream(dest) 替换为您的 ByteArrayOutputStream 实例。
【解决方案2】:

这是不可能的,这种数字签名是专门为保护原始文档不被以任何方式修改而设计的。

要将这两个文档合并和签名,您需要知道用于签名的密钥并为新合并的文档再次生成签名。

【讨论】:

    【解决方案3】:
    1. 在 Adob​​e 中打开签名的 pdf。

    2. 打开打印对话框(Ctrl+P)

    3. 将打印机更改为“Microsoft Print to PDF”然后打印。

    4. 新创建的 PDF 将具有签名,并且将作为普通 pdf 用于合并/合并活动。

    注意:此方法将签名文档转换为标准 pdf。结果显示签名信息,但基础数字签名丢失。在我的例子中,原始签名者理解这种区别。

    创建摘要文件是我的目标。我将各种经过数字签名的文档以及其他相关文档合并到一个摘要 pdf 中。原始的,数字签名的文件,被存储以供将来参考。我越来越相信,在保留基础数字签名的同时,将数字签名的文档合并为一个摘要 pdf 是不可能的。

    需要摘要数据包的用户将从我建议的方法中受益。请记住,在原始数字签名文档可按需提供的范围内,我的方法仍然“合法有效”。

    【讨论】:

    • 显然打印出来的 pdf 不能将原始签名作为有效签名(除非“打印机”只是复制)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多