跳到主要内容

5. 加密对象

  1. 加密对象

COSE 支持两种不同的 encryption 结构. 当不需要 recipient 结构, 因为要使用的 key 是隐式已知时, 使用 COSE_Encrypt0. 其他时候使用 COSE_Encrypt. 这包括存在多个 recipient, 或使用 direct(即 preshared secret)以外 recipient algorithm 的情况.

5.1. Enveloped COSE 结构

enveloped 结构允许消息有一个或多个 recipient. 消息中规定了用于承载关于 content 的 header parameters, 以及关于 recipient information 的 header parameters 的位置. 与 content 关联的 protected header parameters 由 content encryption algorithm 认证. 与 recipient 关联的 protected header parameters(当算法支持时)由 recipient algorithm 认证. 关于 content 的 header parameters 示例包括 content type 和 content encryption algorithm. 关于 recipient 的 header parameters 示例包括 recipient 的 key identifier 和 recipient 的 encryption algorithm.

加密 plaintext 和 key 使用相同技术及几乎相同的结构. 这不同于 "Cryptographic Message Syntax (CMS)" [RFC5652] 和 "JSON Web Encryption (JWE)" [RFC7516] 所采用的方法, 后两者对 content layer 和 recipient layer 使用不同结构. 本文定义两个结构: COSE_Encrypt 用于保存 encrypted content, COSE_recipient 用于保存面向 recipients 的 encrypted keys. enveloped messages 示例见 Appendix C.3.

COSE_Encrypt 结构可根据使用上下文编码为 tagged 或 untagged. tagged COSE_Encrypt 结构由 CBOR tag 96 标识. 表示它的 CDDL 片段为:

COSE_Encrypt_Tagged = #6.96(COSE_Encrypt)

COSE_Encrypt 结构是一个 CBOR array. array 的字段按顺序为:

protected: 如 Section 3 所述.

unprotected: 如 Section 3 所述.

ciphertext: 此字段包含 ciphertext, 编码为 bstr. 如果 ciphertext 要独立于关于 encryption process 的控制信息传输(即 detached content), 则该字段编码为 nil 值.

recipients: 此字段包含 recipient information structures 的 array. recipient information structure 的类型为 COSE_recipient.

对应上述文本的 CDDL 片段为:

COSE_Encrypt = [ Headers, ciphertext : bstr / nil, recipients : [+COSE_recipient] ]

COSE_recipient 结构是一个 CBOR array. array 的字段按顺序为:

protected: 如 Section 3 所述.

unprotected: 如 Section 3 所述.

ciphertext: 此字段包含 encrypted key, 编码为 bstr. 所有已编码 key 都是 symmetric keys; key 的二进制值就是内容. 如果没有 encrypted key, 则此字段编码为 nil 值.

recipients: 此字段包含 recipient information structures 的 array. recipient information structure 的类型为 COSE_recipient(示例见 Appendix B). 如果没有 recipient information structures, 此元素不存在.

对应上述 COSE_recipient 文本的 CDDL 片段为:

COSE_recipient = [ Headers, ciphertext : bstr / nil, ? recipients : [+COSE_recipient] ]

5.1.1. Content Key Distribution Methods

加密消息由 encrypted content 和面向一个或多个 recipient 的 encrypted CEK 组成. CEK 使用每个 recipient 特有的 key 为该 recipient 加密. 该加密的细节取决于 recipient algorithm 所属类别. 每个类别的具体细节见 Section 8.5. 五种 content key distribution methods 的简要摘要如下:

direct: CEK 与先前已分发且已标识的 symmetric key 相同, 或从先前已分发的 secret 派生. 消息中不传输 CEK.

symmetric key-encryption keys (KEKs): CEK 使用先前已分发的 symmetric KEK 加密. 也称为 key wrap.

key agreement: 使用 recipient 的 public key 和 sender 的 private key 生成 pairwise secret, 应用 Key Derivation Function (KDF) 派生 key, 然后 CEK 要么是派生出的 key, 要么由派生出的 key 加密.

key transport: CEK 使用 recipient 的 public key 加密.

passwords: CEK 在从 password 派生出的 KEK 中加密. 截至本文档发布时, 尚未定义 password algorithms.

5.2. Single Recipient Encrypted

COSE_Encrypt0 encrypted 结构不能指定消息的 recipients. 该结构假定 object 的 recipient 已经知道用于解密消息的 key 的身份. 如果需要向 recipient 标识 key, 应使用 enveloped 结构.

encrypted messages 示例见 Appendix C.4.

COSE_Encrypt0 结构可根据使用上下文编码为 tagged 或 untagged. tagged COSE_Encrypt0 结构由 CBOR tag 16 标识. 表示它的 CDDL 片段为:

COSE_Encrypt0_Tagged = #6.16(COSE_Encrypt0)

COSE_Encrypt0 结构是一个 CBOR array. array 的字段按顺序为:

protected: 如 Section 3 所述.

unprotected: 如 Section 3 所述.

ciphertext: 如 Section 5.1 所述.

对应上述 COSE_Encrypt0 文本的 CDDL 片段为:

COSE_Encrypt0 = [ Headers, ciphertext : bstr / nil, ]

5.3. AEAD Algorithms 的加密和解密方式

AEAD algorithms 的 encryption algorithm 相当简单. 第一步是为 authenticated data structure 创建一致的 byte string. 为此, 我们使用 Enc_structure. Enc_structure 是一个 CBOR array. Enc_structure 的字段按顺序为:

  1. 一个 context text string, 用于标识 authenticated data structure 的上下文. context text string 为:

    对 COSE_Encrypt0 data structure 的 content encryption, 为 "Encrypt0".

    对 COSE_Encrypt data structure 的第一层(即 content encryption), 为 "Encrypt".

    对要放入 COSE_Encrypt data structure 的 recipient encoding, 为 "Enc_Recipient".

    对要放入 MACed message structure 的 recipient encoding, 为 "Mac_Recipient".

    对要放入 recipient structure 的 recipient encoding, 为 "Rec_Recipient".

  2. 来自 body structure 的 protected attributes, 编码为 bstr 类型. 如果没有 protected attributes, 则使用零长度 byte string.

  3. 来自应用程序的 externally supplied data, 编码为 bstr 类型. 如果未提供此字段, 它默认为零长度 byte string. (关于构造此字段的应用指导, 见 Section 4.3.)

描述上述文本的 CDDL 片段为:

Enc_structure = [ context : "Encrypt" / "Encrypt0" / "Enc_Recipient" / "Mac_Recipient" / "Rec_Recipient", protected : empty_or_serialized_map, external_aad : bstr ]

如何加密消息:

  1. 创建 Enc_structure 并填充适当字段.

  2. 按 Section 9 所述编码方式, 将 Enc_structure 编码为 byte string (Additional Authenticated Data (AAD)).

  3. 确定 encryption key (K). 此步骤取决于所用 recipient algorithm 的类别. 对于:

    No Recipients: 要使用的 key 由当前 layer 的 algorithm 和 key 确定. 示例包括 key wrap keys (Section 8.5.2) 和 preshared secrets.

    Direct Encryption and Direct Key Agreement: key 由 recipient structure 中的 key 和 algorithm 确定. 要使用的 encryption algorithm 和 key size 是 recipient 所用 KDF 的输入. (对 direct 而言, KDF 可视为 identity operation.) 这些算法的示例见 [RFC9053] Sections 6.1 和 6.3.

    Other: key 随机生成.

  4. 用 K (encryption key), P (plaintext), 以及 AAD 调用 encryption algorithm. 将返回的 ciphertext 放入结构的 "ciphertext" 字段.

  5. 对消息中使用 non-direct algorithms 的 recipients, 以 K (encryption key) 作为 plaintext, 递归执行该 recipient 的 encryption algorithm.

如何解密消息:

  1. 创建 Enc_structure 并填充适当字段.

  2. 按 Section 9 所述编码方式, 将 Enc_structure 编码为 byte string (AAD).

  3. 确定 decryption key. 此步骤取决于所用 recipient algorithm 的类别. 对于:

    No Recipients: 要使用的 key 由当前 layer 的 algorithm 和 key 确定. 示例包括 key wrap keys (Section 8.5.2) 和 preshared secrets.

    Direct Encryption and Direct Key Agreement: key 由 recipient structure 中的 key 和 algorithm 确定. 要使用的 encryption algorithm 和 key size 是 recipient 所用 KDF 的输入. (对 direct 而言, KDF 可视为 identity operation.)

    Other: key 通过解码并解密其中一个 recipient structure 来确定.

  4. 用 K (要使用的 decryption key), C (ciphertext), 以及 AAD 调用 decryption algorithm.

5.4. AE Algorithms 的加密和解密方式

如何加密消息:

  1. 验证 "protected" 字段是零长度 byte string.

  2. 验证此操作没有提供 external additional authenticated data.

  3. 确定 encryption key. 此步骤取决于所用 recipient algorithm 的类别. 对于:

    No Recipients: 要使用的 key 由当前 layer 的 algorithm 和 key 确定. 示例包括 key wrap keys (Section 8.5.2) 和 preshared secrets.

    Direct Encryption and Direct Key Agreement: key 由 recipient structure 中的 key 和 algorithm 确定. 要使用的 encryption algorithm 和 key size 是 recipient 所用 KDF 的输入. (对 direct 而言, KDF 可视为 identity operation.) 这些算法的示例见 [RFC9053] Sections 6.1 和 6.3.

    Other: key 随机生成.

  4. 用 K (要使用的 encryption key) 和 P (plaintext) 调用 encryption algorithm. 将返回的 ciphertext 放入结构的 "ciphertext" 字段.

  5. 对消息中使用 non-direct algorithms 的 recipients, 以 K (encryption key) 作为 plaintext, 递归执行该 recipient 的 encryption algorithm.

如何解密消息:

  1. 验证 "protected" 字段是零长度 byte string.

  2. 验证此操作没有提供 external additional authenticated data.

  3. 确定 decryption key. 此步骤取决于所用 recipient algorithm 的类别. 对于:

    No Recipients: 要使用的 key 由当前 layer 的 algorithm 和 key 确定. 示例包括 key wrap keys (Section 8.5.2) 和 preshared secrets.

    Direct Encryption and Direct Key Agreement: key 由 recipient structure 中的 key 和 algorithm 确定. 要使用的 encryption algorithm 和 key size 是 recipient 所用 KDF 的输入. (对 direct 而言, KDF 可视为 identity operation.) 这些算法的示例见 [RFC9053] Sections 6.1 和 6.3.

    Other: key 通过解码并解密其中一个 recipient structure 来确定.

  4. 用 K (要使用的 decryption key) 和 C (ciphertext) 调用 decryption algorithm.