PDF签名摘要

PDF Signature digest

我有一个关于计算用于数字签名的 PDF 文档摘要的快速问题(与我之前的一个问题有点相关,我想弄清楚为什么您需要知道客户的证书创建正确的摘要)。 在 Adob​​e 关于 PDF 格式的文档中指定了以下内容:

A byte range digest shall be computed over a range of bytes in the file, that shall be indicated by the ByteRange entry in the signature dictionary. This range should be the entire file, including the signature dictionary but excluding the signature value itself (the Contents entry).

所以此时事情看起来相当简单,只需消化除 /Sig 字典中的 /Contents 条目之外的所有内容。 /Contents 条目中的实际数据指定如下:

For public-key signatures, Contents should be either a DER-encoded PKCS#1 binary data object or a DER-encoded PKCS#7 binary data object.

所以仍然没有问题,我可以(可能)生成摘要,为 /Contents 条目保留 space 并稍后附加此 PKCS#7 对象。当我阅读以下内容时开始感到困惑:

Revocation information is a signed attribute, which means that the signing software must capture the revocation information before signing. A similar requirement applies to the chain of certificates. The signing software must capture and validate the certificate's chain before signing.

所以我不太明白:显然 /Contents 条目(包含证书和签名摘要)没有被消化,但证书链是一个签名属性(因此需要被消化?) .

如果有人能进一步准确说明消化的内容,并向我更好地解释签名属性,我将不胜感激。我想回答的主要问题是:我真的可以在事先不知道某人的证书的情况下创建一个可签名的摘要吗? (我正在使用 pkcs7 分离签名)

简而言之:

Can I actually create a signable digest without knowing someone's certificate beforehand?

在子过滤器 ETSI.CAdES.detachedadbe.pkcs7.detached 的情况下,您可以创建 文档摘要 事先不知道某人的证书.

不过,在开始生成要嵌入到 PDF 中的 CMS 签名容器之前,您通常必须知道签名者证书。

详细:

(请注意,以下内容有些简化。)

I can (probably) generate the digest, reserve space for the /Contents entry and attach this PKCS#7 object later on.

如果你先保留space然后生成摘要,确实是这样的。

The confusion starts when I read the following:

Revocation information is a signed attribute, which means that the signing software must capture the revocation information before signing. A similar requirement applies to the chain of certificates. The signing software must capture and validate the certificate's chain before signing.

所以我不太明白:显然 /Contents 条目(包含证书和签名摘要)没有被消化,但证书链是一个签名属性(因此需要被消化?) .

如果有人能进一步准确说明消化的内容,并向我更好地解释签名属性,我将不胜感激。

需要注意的主要事实是,在 PKCS#7/CMS 签名容器的情况下 签名通常不仅仅包括 一个 哈希计算但至少 两个!

第一个散列,文档散列,确实是为 整个文件计算的,包括签名字典但不包括签名值本身(Contents 条目)(您可能想阅读 this answer 了解更多详情)。

但这不是应用签名算法时立即使用的散列。

在 PKCS#7/CMS 签名容器的生成过程中(除非是最原始的形式),您会创建一个名为“签名属性”的结构。

您用多个属性(名称-值对)填充此结构,其中包括已经计算出的文档哈希以及其他属性,例如您阅读的 Adob​​e 风格的撤销信息。

当您完成该结构的创建后,您散列该结构并为其生成签名

然后您可以使用这些已签名的属性、签名和一些未由该签名签名的更多信息,例如,将 PKCS#7/CMS 签名容器放在一起。证书、签名时间戳、...

有关签名容器的更多详细信息,请阅读 this answer

最后将这个签名容器嵌入到 PDF 中的保留 space 中。

The main question that I want to answer is: Can I actually create a signable digest without knowing someone's certificate beforehand? (I'm working with a pkcs7 detached signature)

在子过滤器 ETSI.CAdES.detachedadbe.pkcs7.detached 的情况下,您可以创建 文档摘要 事先不知道某人的证书.

不过,根据 CMS 签名配置文件,您通常必须在开始生成签名容器之前知道签名者证书,因为许多配置文件需要存在引用签名者证书的签名属性。

澄清:

OP 在评论中提出了一些后续问题:

1.: One of the signed attributes is the document hash(without the /contents), so if I understand correctly this is the unsigned hash?

由于“签名属性”最终被散列和签名,其中的文档散列不是立即,而是直接签名但是它是间接 作为此属性结构的一部分进行签名。所以我不会称它为无符号...

  1. In the end when the user really generates a signature, he signs the hash of the PKCS#7 object?

不,“签名属性”结构的散列只是 PKCS#7 对象的一部分,而不是全部。 PKCS#7/CMS 对象的多个部分未签名。

  1. Does the /Contents entry still have a PKCS#7 object that's actually readable for us? (To extract certificates etc for verification)

Contents 条目包含完整的 PKCS#7/CMS 签名容器对象作为二进制字符串。因此,是的,您可以读取它(通过读取该二进制字符串的值)和(如果您有知道如何解析此类签名容器的代码)从中提取信息。

但是请注意,签名容器可能不包含验证所需的所有数据:例如,如果您使用链(而不是 shell)验证模型进行验证,您可能必须从相应的 PDF 签名词典条目。

  1. When verifying a signature, do we simply extract the embedded PKCS#7 object, recalculate the digest, recalculate the digest of the PKCS#7 object and verify this against the signature using the certificate we get from the PKCS#7 object?

您显然还必须计算已签名 PDF 字节范围的摘要,并将该值与包含原始文档摘要的已签名属性进行比较。(您的意思可能是 重新计算摘要.)

如 3 的答案中所述,您可能需要从 PDF 中检索其他信息以用于 PKCS#7 验证。

此外你说我们从 PKCS#7 对象获得的证书 - 请注意 PKCS#7/CMS 签名容器可能包含多个证书。你必须找到正确的。为此应使用 CMS SignerInfo SignerIdentifier 和 ESS 签名属性。

此外,您还必须验证签名者证书的有效性和信任度。

  1. Is there any good documentation on what authenticated attributes there are?

您可以开始阅读了