pdf - 在 PDF 签名中包含时间戳的步骤

标签 pdf digital-signature cryptoapi trusted-timestamp

再会,

我正在尝试将时间戳信息嵌入到 pdf 签名中,以便 adobe 向我报告签名是时间戳。目前,我所取得的成就是 Adob​​e 报告“签名包含嵌入的时间戳,但无法验证”,并且当您查看日期/时间属性时,它说“时间戳权限”不可用并且“显示证书”显示为灰色。

显然,我在构建我的 PKCS#7 消息时做错了什么。但我现在不知道什么。
有人可以通过描述我需要采取的步骤来帮助我,以便我的签名带有时间戳吗?或者建议一个可以帮助我找到问题的工具?

我正在使用加密 API。我目前遵循的步骤如下:

  • 使用 CryptHashMessage 函数 (SHA256) 创建 pdf 数据的摘要。
  • 使用 CryptRetrieveTimeStamp 函数将此摘要发送到 TSA。我已经设置了 *TIMESTAMP_DONT_HASH_DATA* 标志,以便摘要不会再次被散列。
  • 来自 TSA 的回复作为未经身份验证的属性添加到 *CRYPT_SIGN_MESSAGE_PARA* 结构中,并将签名时间添加为经过身份验证的属性。
  • 然后我使用 CryptSignMessage 函数对使用上述结构的原始数据进行签名。

  • 如何检查数据是否正确,以便 adobe 可以向我显示签名已加时间戳?

    问候,
    玛格达

    最佳答案

    简而言之:您正在为错误的数据加时间戳,请参阅答案的底部。
    您的签名与 Adob​​e 的签名之间的主要区别:

  • Adobe 的签名包含签名的撤销信息属性;该属性不包含任何实际的撤销信息。
    由于此属性是可选的,因此它不应与此处相关。
  • 您的签名包含签名的签名时间属性。
    由于您还嵌入了时间戳,因此不需要签名时间,但也不禁止。
  • 您的签名的 signatureAlgorithm 值为 1.2.840.113549.1.1.1,即 RSA 加密而 Adob​​e 是 1.2.840.113549.1.1.11,即 sha256WithRSA加密
    在这里,Adobe 的选择无疑是更好的选择,但 Adob​​e Reader 似乎忽略了您签名中的不足:毕竟,它说文档自签名后就没有更改过。
  • 在您的签名中,时间戳标记 PDF 文档的哈希值,即与签名的签名 messageDigest 属性相同,而在 Adob​​e 签名中,时间戳标记不同的。
    砰。这就是问题。诚然,您在最初的问题中已经说过,但它并没有引起我的注意:
  • 使用 CryptHashMessage 函数 (SHA256) 创建 pdf 数据的摘要。
  • 使用 CryptRetrieveTimeStamp 函数将此摘要发送到 TSA。我已经设置了 TIMESTAMP_DONT_HASH_DATA 标志,以便摘要不会再次被散列。

  • 这是错误的!根据规范,时间戳作为未签名的属性添加:

    Time stamp information as an unsigned attribute (PDF 1.6): The timestamp token shall conform to RFC 3161 and shall be computed and embedded into the PKCS#7 object as described in Appendix A of RFC 3161.


    (section 12.8.3.3.1 of ISO 32000-1)

    *And RFC 3161 states:*
    

    The value of messageImprint field within TimeStampToken shall be a hash of the value of signature field within SignerInfo for the signedData being time-stamped.


    (Appendix A of RFC 3161)

    *Thus, **you are time stamping the wrong hash!** Adobe correctly expects you to time stamp the signature. So you should first create a regular signature, then look up its signature value, hash & time stamp that value, and then add that time stamp to the signature container signer info as unsigned time stamp attribute.*
    
    *Unfortunately I don't know the Windows Crypto API well enough to explain how to do that; I'm more at home in the Java crypto api.*
    

    关于pdf - 在 PDF 签名中包含时间戳的步骤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18761993/

    相关文章:

    java - 以编程方式签署 JAR

    python - 将从 .NET 导出的 CSP blob 导入到 python pyCrypto 中

    c++ - 使用 CryptoApi 向证书添加扩展名

    javascript - 如何在 PDF 中使用 JavaScript 来识别用户的操作系统

    java - 无法从 CMSSigned 数据获取 SignerCertificate

    c# - 如何使用 ItextSharp 检索数字签名信息(名称、日期...)

    java - Xml 签名在 .NET 中验证正常,但在 Java 中验证失败

    macos - 如何验证系统中安装的客户端证书

    javascript - 如何通过 JavaScript 与 iframe 中嵌入的 PDF 文档进行交互?

    perl - 如何使用 Perl 和 CAM::PDF 读取 PDF 文档属性?