首页 > 解决方案 > iTextSharp 不呈现数字签名

问题描述

我已经阅读了 I-TEXT 数字签名电子文本,以及 MKL 之前回答的帖子(他似乎是与布鲁诺一起在这个主题上的权威)。

本质上,我有一个 Azure 应用程序服务,它从公司的签名 API 获取数字签名(base 64)和证书链。该公司的签名 API 返回 Base64 中的签名以及证书链。

我只想将签名对象/容器插入到 pdf 中,这样当最终用户打开 pdf 时,它将显示在签名面板中。我更喜欢使用延迟签名。

我已经从第 4 章的“clientseversigning 示例”转移到了 MKL 的“如何在不及早知道签名者证书的情况下创建 PDF 签名”中的延迟签名。

Company API 返回一个“普通”签名,我很确定,并且还返回一个由 3 个字符串证书组成的链。

我应该注意我确实提前拥有根证书和子证书(2 个 .cer 文件),但我现在没有在“准备”用于散列的 pdf 中使用它们,因为延迟签名示例显然没有使用它们。对于容器构建代码(从 Company API 获得响应后),我使用了从 company API 返回的 3 个 certs 链,但我也尝试了 2 个 .cer 文件,但无济于事。

我的代码与示例中的代码之间的唯一区别是而不是 byte[] certificateBytes = THE_RETRIEVED_CERTIFICATE_BYTES; X509Certificate x509Certificate = new X509CertificateParser().ReadCertificate(certificateBytes); 我构建了 3 个 x509Certificates(一个用于从 Company API 返回的链中的每个字符串。

遗憾的是,事情无法正常工作,我在 Acrobat 中收到以下错误:签名无效,此签名中包含的格式或信息有错误,签名的身份尚未验证,签名时间来自签名者计算机上的时钟...另外,如果我在 Acrobat 中单击此错误下方的证书详细信息,则它是空白的。这几乎是我在尝试“clientserversigning 示例”时遇到的错误

我真的很努力,想知道它可能是什么......我应该尝试从 12000 修改估计大小并将其提高吗?或者我在 Acrobat 中遇到的错误,也许他们暗示来自公司 API 的证书链没有被签名延迟容器构造代码拾取......我正在努力,但任何提示都会非常感激

埃文


为了澄清起见,我正在关注第 4 章的 clientserversigningexample 但是一旦使用公司 API 的签名重新创建了我的 pdf,我就会得到以下内容

生成的 pdf 未正确签名

它的说法 1) 信息格式有错误 2) 签名者的身份尚未验证 3) 签名时间来自签名者计算机上的时钟

现在就在散列发送以进行签名之前“准备”pdf ......我在 ClientSigning 示例中没有看到任何专门准备它的内容,我可以假设 IText 库正在后台准备它吗?

标签: pdfitextdigital-signature

解决方案


在您的问题和对它的评论中,您似乎特别感兴趣

  • 是否可以使用仅将证书与签名一起返回的签名 API,以及
  • 何时延期签约。

您可以使用仅在签名后提供用户证书的签名 API

要回答这个问题,首先必须澄清所讨论的签名 API 创建什么样的签名,普通签名值(例如 PKCS#1 RSA 签名)或成熟的 CMS 签名容器。

如果它创建成熟的 CMS 签名容器,您可以根据任意签名配置文件创建签名,只要签名容器遵循它们的要求(他们经常这样做)。他们唯一的限制是您不能在签名可视化中获得来自签名者证书的信息,因为该可视化是在 PDF 的签名数据中定义的。

如果它只创建普通签名值,那么您可以做的最好的事情是创建并嵌入简单的 CMS 容器,这些容器不包含指向签名者证书的指针(如果它们有任何签名属性作为开始)。许多感兴趣的签名策略确实需要这样的指针,但至少 Adob​​e Reader 接受没有这样的签名。

如果您处于这种情况并想尝试使用这种简单的签名容器创建签名,您可能需要使用此答案中的代码,“如何在不及早知道签名者证书的情况下创建 PDF 签名”部分。

何时使用延迟签名

延迟签名和其他 iText 签名调用之间的区别在于延迟签名需要更少的信息(与ExternalContainer 签名相比)。

与其他 iText 签名方法相比,它signDeferred 重新使用PDF 的最外层现有的填充签名字段进行签名,并且仅替换其中的签名容器。

方法名称源自它用于的最常见用例:

  • 在第一步中,(可能首先创建然后)使用计算要签名的文档哈希但不返回最终 CMS 容器signExternalContainer的实现填充签名字段,仅返回一些(通常)空数组。IExternalSignatureContainer然后将生成的带有填充签名字段的 PDF(尽管没有最终签名容器)临时存储(在文件系统或数据库中)。
  • 在第二步中,请求并(可能异步地)等待确定的文档散列的签名容器。
  • 在最后一步signDeferred中,用于将检索到的签名容器注入到第一步准备的 PDF 中。

这种延迟签名过程通常在第二步(签名容器创建和检索)的设置中是首选的,它可能需要比希望保持签名文档所需资源阻塞的时间更长的时间。这尤其包括由远程服务器或客户端生成的签名,尤其是在该签名过程等待某些第三方许可或激活的情况下。


推荐阅读