PKCS#7 CMS - 消息摘要計算過程
我正在研究 RFC 5652,以便確切了解如何編碼/解碼 PKCS#7 ASN.1 數據。
我不明白當存在“signedAttrs”欄位時如何創建簽名:
消息摘要計算過程的結果取決於 signedAttrs 欄位是否存在。當該欄位不存在時,結果只是如上所述的內容的消息摘要。但是,當該欄位存在時,結果是包含在 signedAttrs 欄位中的 SignedAttrs 值的完整 DER 編碼的消息摘要。由於 SignedAttrs 值(如果存在)必須包含 content-type 和 message-digest 屬性,因此這些值會間接包含在結果中。
通過閱讀上面的文字,我感到困惑: SignedAttrs 欄位包含消息摘要和內容類型值,但消息摘要可以在計算後出現,並且必須計算摘要:
eContent OCTET STRING + SignedAttrs 欄位的完整 DER 編碼(包含消息摘要欄位)。
在下面的範例中,有一個 PKCS#7 已簽名資料結構,其中正在對信封數據內容欄位值 + 已簽名屬性進行簽名。messageDigest 值究竟來自哪裡?
PKCS7/CMS 設想的簽名方案使用兩個階段,首先對要簽名的數據進行雜湊處理,然後將雜湊用於簽名生成和驗證(RSA、EG、DSA 和 ECDSA)。對於您的範例——帶有 SHA1 的 RSASSA-PKCS1-v1_5——一些數據使用 SHA1 進行散列,並且該散列被編碼、填充和 modexp’ed,這在 PKCS1 和 PKCS7 的舊版本中被描述為“使用私鑰”,儘管該描述被發現是有害的並且不再使用。(請參閱我的https://security.stackexchange.com/questions/159282/#159289以了解此處的一些 Qs/As 以及有關此主題的 security.SX,您可以通過搜尋找到更多內容。)
PKCS7 最初只是簡單地將這個過程應用於數據(現在是 eContent)。它及其後繼 CMS 得到了增強,以允許該基本流程或兩階段流程:
- 計算 eContent(您的第一個紅色括號)的(值)的雜湊值,並將該值放置在 signedAttrs 的 messageDigest 屬性中。此外,eContentType 被複製到 signedAttrs 中的 contentType 屬性。可能會添加其他屬性,並且一些基於 CMS 的標准定義了對 signedAttrs 中屬性的附加要求。
- (一種編碼)signedAttrs 結構是有符號的。這幾乎是您的第二個紅色括號,除瞭如下所述修改了標籤。
這兩個選項的規範混合在文件中。首先註意上一節(5.3)定義了signedAttrs:
signedAttrs is a collection of attributes that are signed. The field is optional, but it MUST be present if the content type of the EncapsulatedContentInfo value being signed is not id-data. SignedAttributes MUST be DER encoded, even if the rest of the structure is BER encoded. Useful attribute types, such as signing time, are defined in Section 11. If the field is present, it MUST contain, at a minimum, the following two attributes: A content-type attribute having as its value the content type of the EncapsulatedContentInfo value being signed. Section 11.1 defines the content-type attribute. However, the content-type attribute MUST NOT be used as part of a countersignature unsigned attribute as defined in Section 11.4. A message-digest attribute, having as its value the message digest of the content. Section 11.2 defines the message-digest attribute.
您引用的部分(5.4)然後更完整地說:
[With or without signedAttrs] the initial input to the message digest calculation process is the "value" of the encapsulated content being signed. Specifically, the initial input is the encapContentInfo eContent OCTET STRING to which the signing process is applied. Only the octets comprising the value of the eContent OCTET STRING are input to the message digest algorithm, not the tag or the length octets. The result of the message digest calculation process depends on whether the signedAttrs field is present. When the field is absent, the result is just the message digest of the content as described above. When the field is present, however, the result is the message digest of the complete DER encoding of the SignedAttrs value contained in the signedAttrs field. Since the SignedAttrs value, when present, must contain the content-type and the message-digest attributes, those values are indirectly included in the result. The content-type attribute MUST NOT be included in a countersignature unsigned attribute as defined in Section 11.4. A separate encoding of the signedAttrs field is performed for message digest calculation. The IMPLICIT [0] tag in the signedAttrs is not used for the DER encoding, rather an EXPLICIT SET OF tag is used. That is, the DER encoding of the EXPLICIT SET OF tag, rather than of the IMPLICIT [0] tag, MUST be included in the message digest calculation along with the length and content octets of the SignedAttributes value.
打破它:沒有 signedAttrs 的 eContent 的雜湊用於第 5.5 節中的簽名。使用signedAttrs,signedAttrs 的散列——只有signedAttrs,其編碼的標籤如所述被修改——用於5.5 中的簽名。但是由於 signedAttrs 的內容包括 eContent 的雜湊值和 eContentType 的值,因此簽名也有效地保護了它們:如果您更改 eContent 而不更改 signedAttrs,那麼驗證器將檢測到 hash(eContent) 與 signedAttrs.messageDigest 不匹配,並且如果您更改 eContent和signedAttrs.messageDigest,則驗證程序將檢測到簽名對於修改後的 signedAttrs 無效。
When the signedAttrs field is absent, only the octets comprising the value of the SignedData encapContentInfo eContent OCTET STRING (e.g., the contents of a file) are input to the message digest calculation. This has the advantage that the length of the content being signed need not be known in advance of the signature generation process. Although the encapContentInfo eContent OCTET STRING tag and length octets are not included in the message digest calculation, they are protected by other means. The length octets are protected by the nature of the message digest algorithm since it is computationally infeasible to find any two distinct message contents of any length that have the same message digest.
這更冗長地重複了,沒有signedAttrs 的 eContent 的雜湊用於 5.5 中的簽名。
5.5然後完成序列:
The input to the signature generation process includes the result of the message digest calculation process and the signer's private key. The details of the signature generation depend on the signature algorithm employed. [...]
用於簽名生成(和驗證)的“消息摘要計算過程的結果”——如 5.4 中所定義——是:(不帶signedAttrs)eContent 值的散列或:(帶signedAttrs)的散列signedAttrs 的編碼。