PDF 签名在 TSA 时间戳后无效

问题描述 投票:0回答:1

我尝试在 PHP 中使用 TCPDF 来签署 pdf 文档。 签名似乎工作正常,但在我将 Base64 pdf 文件发送给 TSA 以获取文档时间戳后。 我的签名无效(在 Adobe 中:字节范围无效)。问题是什么造成的?

  • 我使用了符号级别2。
  • 我尝试过使用不同的签署文件(已经由其他人签署)给 TSA,但它工作正常。
  • 我在 .PEM 文件中使用了私钥和公钥。
  • 我猜测问题出在签名过程上,但不知道更多。

这是我的时间戳之前的字节范围 /字节范围[0 1208654 1220398 12856] 这是时间戳之后我的字节范围 /字节范围[0 1208655 1220399 12856]

php pdf digital-signature tcpdf pades
1个回答
0
投票

(我使用“PAdES(UTC日期时间格式)”文件夹中的最新文件进行分析,但结果似乎也适用于您之前的尝试。)

这非常奇怪。试验和错误表明,原始签名修订版的最后“%%EOF”字节之后的第一个字节可以使 Adobe Acrobat 相信签名的某些无效ByteRange。 PDF 规范不支持这一点。

详细:

您签名的(但尚未加时间戳)PDF 以“%%EOF”字节结尾,没有尾随行尾:

Adobe Acrobat 验证对此签名感到满意。

然后,您使用的时间戳服务会在添加自己的对象作为文件的增量更新之前添加 CRLF 行尾:

Adobe Acrobat 突然称签名无效,因为ByteRange 无效。但是您的签名覆盖了整个文件(除了签名 Contents 值)及其字节范围

[0 1462644 1474388 12838]
,因此 Acrobat 错误消息“签名字节范围无效”显然是错误的。

另一方面,使用 Adobe Acrobat 对签名文件添加时间戳不会导致同样的问题。

最终比较您的服务器和 Adobe Acrobat 的时间戳文件(在分析了许多其他差异之后)表明,看似微小的差异会产生重大影响,Acrobat 仅在其增量更新对象之前附加一个 LF:

将带时间戳的签名文件中“%%EOF”后面的 CRLF (0D 0A) 替换为例如CR SPACE (0D 20),Adobe Acrobat 突然再次对签名感到满意(显然不再对时间戳感到满意,毕竟我更改了带时间戳的修订版)。

另一方面,用 SPACE LF (20 0A) 替换并不会让 Acrobat 满意。显然,“%%EOF”后第二个字节中的 LF 会触发 Adobe Acrobat 中的某些内容,使其认为前面的签名无效。

你应该做什么:

我不记得以前遇到过这个问题。不过,通常情况下,我处理的签名 PDF 在签名字节范围中包含的“%%EOF”之后已经带有行尾标记。因此,我假设只有在签名的字节范围以“%%EOF”结尾且没有 EOL 的情况下才会出现问题,只有对于此类文件,Acrobat 才会出现奇怪的反应。

因此,在计算字节范围和签名之前,您应该在“%%EOF”之后添加 EOL。

如果这是不可能的(例如,由于您使用的 PDF 库的限制),您还可以考虑在将签名文件转发到时间戳服务之前将 CR SPACE (0D 20) 附加到您的签名文件中。

谁错了?

这里的根本问题是 PDF 规范并不完全清楚原始 PDF 中带有“%%EOF”的最终“行”是否需要用 EOL 来分隔。我已经习惯了人们同意这两种选择,无论有没有 EOL,都是允许的。

Adobe Acrobat 在其签名验证代码中似乎对这个主题有一个扭曲的想法,要么是由于明确的测试,要么是由于对签名修订版的“修复”。

© www.soinside.com 2019 - 2024. All rights reserved.