简而言之:
我可以在事先不知道某人的证书的情况下创建一个可签名的摘要吗?
如果是子过滤器 ETSI.CAdES.detached 或 adbe.pkcs7.detached,您可以在不知情的情况下创建 文档摘要 事先某人的证书。
不过,在开始生成要嵌入 PDF 的 CMS 签名容器之前,您通常必须知道签名者证书。
详细说明:
(请注意,以下内容有些简化。)
我可以(可能)生成摘要,为 /Contents 条目保留空间并稍后附加此 PKCS#7 对象。
如果您先保留空间然后生成摘要,这确实是事情的完成方式。
当我阅读以下内容时,困惑就开始了:
吊销信息是一个签名属性,这意味着签名软件必须在签名之前捕获吊销信息。类似的要求适用于证书链。签名软件必须在签名前捕获并验证证书链。
所以我不太明白:显然 /Contents 条目(包含证书和签名摘要)没有被消化,但证书链是一个签名属性(因此需要被消化?)。
如果有人能进一步准确说明所消化的内容,我将不胜感激,或许可以更好地向我解释签名的属性。
必须注意的主要事实是,在 PKCS#7/CMS 签名容器的情况下,签名通常不仅包括 一个哈希计算,而且至少包括 两个!
第一个散列,文档散列,确实是针对整个文件计算的,包括签名字典但不包括签名值本身(Contents条目)(您可能想阅读this answer 了解更多详情)。
但这不是在应用签名算法时立即使用的哈希。
在 PKCS#7/CMS 签名容器的生成过程中(除非是最原始的形式),您会创建一个名为“签名属性”的结构。
您使用多个属性(名称-值-对)填充此结构,其中包括已计算的文档哈希以及其他属性,例如您读到的 Adobe 风格的撤销信息。
当您完成创建该结构后,您对该结构进行散列并为其生成签名。
然后,您可以使用这些签名属性、签名和其他一些未由该签名签名的信息来组合 PKCS#7/CMS 签名容器,例如证书,签名时间戳,...
有关签名容器的更多详细信息,请阅读this answer。
最后你将这个签名容器嵌入到 PDF 的保留空间中。
我要回答的主要问题是:我真的可以在事先不知道某人的证书的情况下创建一个可签名的摘要吗? (我正在使用 pkcs7 分离签名)
如果是子过滤器 ETSI.CAdES.detached 或 adbe.pkcs7.detached,您可以在不知情的情况下创建 文档摘要 事先某人的证书。
但是,根据 CMS 签名配置文件,您通常必须在开始生成签名容器之前知道签名者证书,因为许多配置文件需要存在引用签名者证书的签名属性。
说明:
OP 在评论中提出了一些后续问题:
1.:签名属性之一是文档哈希(没有 /contents),所以如果我理解正确,这是未签名的哈希?
由于“签名属性”最终被散列和签名,其中的文档散列不是立即直接签名而是它是间接作为该属性结构的一部分进行签名。所以我不会称之为未签名的......
- 到底用户真正生成签名时,是对PKCS#7对象的hash签名?
不,“签名属性”结构的哈希只是 PKCS#7 对象的一部分,而不是全部。 PKCS#7/CMS 对象的多个部分未签名。
- /Contents 条目是否还有一个我们实际上可读的 PKCS#7 对象? (提取证书等进行验证)
Contents 条目确实包含一个完整的 PKCS#7/CMS 签名容器对象作为二进制字符串。因此,是的,您可以读取它(通过读取该二进制字符串的值)并(如果您有知道如何解析此类签名容器的代码)从中提取信息。
但请注意,签名容器可能不包含验证所需的所有数据:例如,如果您使用链式(而非外壳)验证模型进行验证,则可能必须从相应的 PDF 签名字典条目中提取签名时间。
- 在验证签名时,我们是否只是简单地提取嵌入的 PKCS#7 对象、重新计算摘要、重新计算 PKCS#7 对象的摘要并使用从 PKCS#7 对象获得的证书与签名进行验证?
您显然还必须计算签名 PDF 字节范围的摘要,并将该值与包含原始文档摘要的签名属性进行比较。(您可能是指 重新计算摘要。)
如对 3 的回答中所述,您可能必须从 PDF 中检索其他信息以用于 PKCS#7 验证。
此外,您说我们从 PKCS#7 对象获得的证书 - 请注意 PKCS#7/CMS 签名容器可能包含多个证书。你必须找到正确的。为此应使用 CMS SignerInfo SignerIdentifier 和 ESS 签名属性。
此外,您还必须验证签名者证书的有效性和信任度。
- 有什么好的文档说明有哪些经过身份验证的属性?
你可以开始阅读了