美好的一天,
我正在尝试将时间戳信息嵌入到 pdf 签名中,以便 Adobe 向我报告签名是时间戳。目前,我所取得的成就是Adobe报告"签名包含嵌入的时间戳,但无法验证",当您查看日期/时间属性时,它说"时间戳颁发机构"不可用,并且"显示证书"灰显。
显然,我在构建我的 PKCS#7 消息时做错了。但我现在不知道什么。有人可以帮我描述我需要采取的步骤,以便我的签名带有时间戳吗?或者建议一个可以帮助我找到问题的工具?
我正在使用加密 API。我目前遵循的步骤如下:
- 使用 CryptHashMessage 函数 (SHA256) 创建 pdf 数据的摘要。
- 使用 CryptRetrieveTimeStamp 函数将此摘要发送到 TSA。我已经设置了 *TIMESTAMP_DONT_HASH_DATA* 标志,以便摘要不会再次被哈希处理。
- 来自 TSA 的响应将作为未经身份验证的属性添加到 *CRYPT_SIGN_MESSAGE_PARA* 结构中,签名时间将作为经过身份验证的属性添加。
- 然后我使用 CryptSignMessage 函数对使用上述结构的原始数据进行签名。
如何检查数据是否正确,以便 Adobe 可以向我显示签名已加盖时间戳?
问候玛格达
简而言之:您正在为错误的数据添加时间戳,请参阅答案的底部。
您的签名与 Adobe 签名之间的主要区别:
- Adobe 的签名包含签名吊销信息
属性;此属性不包含任何实际的吊销信息。
由于此属性是可选的,因此在此处不应相关。
您的签名包含签名签名时间属性。
由于您还嵌入了时间戳,因此签名时间不是必需的,但也不是禁止的。
您的签名的签名算法值为 1.2.840.113549.1.1.1,即 RSA 加密,而 Adobe 的签名值为 1.2.840.113549.1.1.11,即 sha256WithRSAEncryption
在这里,Adobe的选择肯定是更好的选择,但Adobe Reader似乎忽略了您签名中的缺陷:毕竟,它说文档自签名以来没有被更改过。
在您的签名中,时间戳会标记PDF文档的哈希值,即与签名的签名messageDigest属性中的哈希值相同,而在Adobe的签名中,时间戳
会标记不同的哈希值。砰。这就是问题所在。诚然,你在最初的问题中说过,但它没有引起我的注意:
使用 CryptHashMessage 函数 (SHA256) 创建 pdf 数据的摘要。
使用 CryptRetrieveTimeStamp 函数将此摘要发送到 TSA。我已经设置了TIMESTAMP_DONT_HASH_DATA标志,以便摘要不会再次被哈希处理。
这是错误的!时间戳根据规范添加为无符号属性:
作为
无符号属性的时间戳信息(PDF 1.6):时间戳令牌应符合RFC 3161,并应按照RFC 3161附录A中所述计算并嵌入到PKCS#7对象中。
(ISO 32000-1 第 12.8.3.3.1 节)
RFC 3161 指出:
TimeStampToken 中的 messageImprint 字段的值应是 SignerInfo 中签名字段值的哈希
值,用于时间戳签名数据。(RFC 3161 附录 A)
因此,您正在为错误的哈希码加盖时间戳!Adobe 正确地希望您为签名添加时间戳。因此,您应该首先创建一个常规签名,然后查找其签名值、哈希和时间戳该值,然后将该时间戳作为未签名时间戳属性添加到签名容器签名者信息中。
不幸的是,我对 Windows 加密 API 的了解还不够好,无法解释如何做到这一点;我对Java加密API更熟悉。
未正确完成。检查我的哑剧库。您需要添加一个未经身份验证的字段,其中 oID 为"1.2.840.113549.1.9.16.2.14"。