【问题标题】:JVM: signing a PDF file in three stepsJVM:分三步签署 PDF 文件
【发布时间】:2020-05-24 15:40:39
【问题描述】:

我有一个网站,允许用户签署任何给定的上传文件。工作流程是:

  1. 用户上传文件。计算文件的 SHA256 摘要并将其存储在数据库中。
  2. 其他用户使用 RSA 对 SHA256 摘要进行签名。签名被添加到数据库中。
  3. 用户可以下载文件和签名(目前在单独的文件中)。签名文件是根据要求生成的。签名文件基本上是 HTML 文件,包含 Base64 和 QRCode 格式的校验和、签名和证书,可以打印以进行归档。

此外,该数据库还包含用户的公钥和证书(以及非技术用户的加密私钥,以便应用可以为他们处理整个签名签名过程)。

现在我想调整工作流程以对 PDF 文件提供特定支持,因为 PDF 文件具有对签名的特定支持。我在 PDFBox 上苦苦挣扎了几天,并成功单独签署了一个 PDF 文件,但我不知道如何适应我通常的工作流程。

PDFBox的签名用法目前是:

ExternalSigningSupport externalSigning =
                document.saveIncrementalForExternalSigning(output);

byte[] cmsSignature = sign(externalSigning.getContent());

externalSigning.setSignature(cmsSignature);

然后将签名的 PDF 文件流式传输到 output

摘要和签名的计算以及将签名和证书合并到 PDF 文件是在上面的“签名”方法中一步完成的,这意味着我不知道如何实现我通常的工作流程计算摘要(1)、签名(2)和生成签名文件(3)分三个步骤。此外,我假设externalSigning.getContent()给出的InputStream不包含整个PDF文件,这意味着无法使用我现有的代码检查摘要和签名?

【问题讨论】:

  • 您不必因为 PDF 签名就使用它。您可以只使用自己的系统并像对待任何其他文件一样处理 pdf 文件。或者,如果您想保留 PDF 签名的一些好处,可以同时使用这两种方法。
  • 如果您想通过多个步骤使用 pdfbox 创建集成的 pdf 签名,您可以从 eSignature DSS 的做法中获得启发。他们还坚持多步骤签名,甚至不想将准备好的 pdf 保留为临时数据,因此他们生成了两次相同的文件。

标签: java pdf rsa pdfbox digital-signature


【解决方案1】:

编辑后的工作流程,即用

  1. 其他用户使用 RSA 对 SHA256 摘要进行签名。签名被添加到数据库中。

而不是

  1. 用户使用 RSA 对 SHA256 摘要进行签名。签名被添加到数据库中。

不能用于可互操作的 PDF 签名,因为它们

  • 每个嵌入式 CMS 签名容器只允许一个 SignerInfo
  • 需要签名来签署完整的当前文档修订版,除了签名容器的占位符:

(更多背景和参考资料请阅读this answer。)

因此,多个用户的签名会签署不同的哈希值,并且(对您的架构而言可能更糟)各自的哈希值取决于所有先前签名的签名值。此外,如果您想要带有签名可视化的签名,其中包含 PDF 中签名者的信息,这些可视化应该是签名内容本身的一部分;之后添加它们会导致有关更改字段属性的消息,这是人们通常不乐意看到的签名字段。


不过,如果您正在寻找可互操作的 PDF 签名之外的内容,还有一些选择。例如。 PDF/CAdES-A(一种允许在 PDF 签名字段中使用任意 CAdES-A 签名的专有格式)忽略“每个嵌入式 CMS 签名容器单个 SignerInfo”限制,因此可以允许实际的并行签名。

当然,这种不可互操作的签名通常不会按照通用查看器和验证器的要求显示和验证。例如。 Adobe Reader 将仅显示 PDF/CAdES-A 并行签名的签名者之一的信息。

【讨论】:

    【解决方案2】:

    为此,您必须在添加签名字段后存储 PDF,因为 pdf 哈希还包括签名字段属性。如果您尝试在第 3 步再次将签名字段添加到原始 pdf,则存储的签名不是与新哈希匹配的签名。您需要检查 PDFBox 是否以及如何允许这样做!

    【讨论】:

    • 好吧,他不必存储它,也可以以相同的方式重新生成它(这个问题与随机数有关用于 AES 加密的情况目前正在解决中)。尽管如此,在我看来,暂时存储它也是更好、更清洁的选择。
    • 我的意思是 Signature 字段也有 /M 字段与时间,因此,可能不可能有相同的时间,因此相同的哈希值与我们在计算时得到的哈希值匹配签名!
    • 好吧,另外一个问题是几个用户可以签署原始文档,我想生成一个包含所有签名和证书的文件。如果我理解得很好,两个用户不能签署“相同”的文件。相反,第二个用户签署了前一个用户签署的文档。摘要不一样:(
    • "我的意思是 Signature 字段也有 /M 字段和时间,因此,可能不可能有相同的时间和相同的哈希值来匹配我们得到的哈希值计算签名的时间!” - M 条目是可选的,签名时间也可以从 CMS 签名容器中的签名时间属性或CMS 签名容器。或者可以在两次运行中将条目设置为相同的时间。如其他地方所述,eSignature DSS 使用 PDFBox 以这种两遍方式进行签名。
    • @scand1sk "嗯,另外一个问题是几个用户可以签署原始文件,我想生成一个包含所有签名和证书的文件。如果我理解得很好,两个用户不能签署“相同”文件。相反,第二个用户签署了前一个用户签署的文档。摘要不一样 :( " - 实际上,这种架构不适合 PDF 签名。可互操作的 PDF 签名不允许真正的并行签名,仅允许串行签名。
    猜你喜欢
    • 2010-12-20
    • 2018-03-23
    • 1970-01-01
    • 2013-04-08
    • 2016-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多