首页 > 解决方案 > 无效的签名。签名验证时出错

问题描述

我正在尝试从外部远程服务签署文档。签署过程分两个阶段进行。远程服务在第一阶段期待base64 编码的哈希,并在身份验证后发出令牌,在第二阶段,我们再次使用接收到的令牌传递相同的哈希并获得base64 签名的哈希。我在这里附上签名不正确的文件。 文档

如果有人可以分析它并指导我评估无效签名背后的原因。我iText7用于执行 pdf 相关操作。

更新

根据反馈,我做了一些更正。该文件现在正在更改。 更改的文件

标签: digital-signatureitext7

解决方案


您的第一个示例文件

本节重点介绍原始示例文件document - 2021-05-01T170114.722.pdf

PDF中有两个明显的问题。由于您不分享您的关键代码,我只能猜测原因。

文件中有两个 PDF

您共享的 111794 字节长的文件实际上是两个 PDF 的串联,第一个是准备签名的 PDF,仅00在签名容器占位符中使用 s,然后是同一个文件,其中包含其他内容。这两个 PDF 中的每一个都正好是 55897 字节长。

造成这种情况的一个典型原因是使用以文件模式Append而不是打开的文件流进行输出Create,可能与使用相同的文件作为输入和输出相结合。

不正确的签名容器

您使用子过滤器adbe.pkcs7.detached创建了一个签名。这意味着要嵌入签名占位符的数据必须是 CMS 签名容器(CMS 是 PKCS#7 的继承者)。但是,在您的签名文件中,只有一个裸签名值,没有签名容器。

造成这种情况的一个典型原因是IExternalSignatureContainer在签名期间使用了一个实现(通常在PdfSigner.signDeferredor的上下文中PdfSigner.signExternalContainer),其sign方法错误地返回了一个裸签名值,而不是一个签名容器。

一般来说

您描述的用例,即使用需要哈希并返回签名哈希的签名服务,听起来您的服务确实只返回一个裸签名值,没有签名容器。

一般来说,这是一种典型的情况,即使用延迟签名,而是使用PdfSigner.signDetachedIExternalSignature方法sign首先散列其参数字节数组,然后将散列值传递给服务并检索签名散列,最后返回该签名散列.

您的第二个示例文件

本节重点介绍第一次更新中的示例文件,文档 - 2021-05-03T200650.926.pdf

正如您所说,您进行了更正以解决上面列出的第一个文件的问题。在您的第二个文件中找到的问题很详细。尽管如此,你仍然没有分享你的关键代码,所以我仍然只能猜测问题的原因。

不正确的messageDigest属性值

在您的签名中,您使用 SHA256 散列算法。

签名属性具有以下messageDigest值:

80FE8AC2DE959A2C791A72A68176EB312D77BD201F8D07CD5A42CC9A4370AAFB

但这与 PDF 的带符号字节的哈希不匹配,即

83134B9C1C7CAE9E4FB0A1FCB37A30A6783F81AF70F6EF4B68865E83C2E11717

显然,您的散列计算例程有错误,或者您只是散列了错误的数据。由于您没有显示您的代码,我无法判断您做错了什么。

有符号哈希值不正确

您的签名字节对哈希值进行签名

80FE8AC2DE959A2C791A72A68176EB312D77BD201F8D07CD5A42CC9A4370AAFB

但这与签名属性的哈希不匹配

9C0D3D2249E69AFA1078F03159332C439B8407A526CBA77C9E9B2701A7EE8131

显然,您的散列计算例程有错误,或者您只是散列了错误的数据。由于您没有显示您的代码,我无法判断您做错了什么。

唯一明显的是您在两种情况下都声明了相同的哈希值。但是这些哈希值重合是非常不合理的。


推荐阅读