3. Header Parameters
- Header Parameters
COSE 的结构设计包含两个信息 bucket. 这些信息不被视为 payload 本身的一部分, 但用于保存关于 content, algorithms, keys, 或 layer 处理所需 evaluation hints 的信息. 除 keys 外, 所有结构都可以使用这两个 bucket. 虽然这些 bucket 存在, 但它们并不总是在所有实例中都可用. 例如, protected bucket 虽然被定义为 recipient 结构的一部分, 但某些用于 recipient 结构的算法不提供 authenticated data. 在这种情况下, protected bucket 留空.
两个 bucket 都实现为 CBOR maps. map key 是一个 "label" (Section 1.5). value 部分取决于该 label 的定义. 两个 map 使用同一组 label/value pairs. label 的 integer 和 text-string 值被划分为若干区段, 包括 standard range, private use range, 以及依赖于所选算法的 range. 已定义的 labels 见 "COSE Header Parameters" IANA registry (Section 11.1).
这两个 bucket 为:
protected: 包含关于当前 layer 且受密码学保护的 parameters. 如果它不会被包含在 cryptographic computation 中, 此 bucket MUST 为空. 在消息中, 此 bucket 编码为 binary object. 该值通过对 protected map 进行 CBOR 编码, 并将其封装在 bstr object 中得到. sender SHOULD 将零长度 map 编码为零长度 byte string, 而不是零长度 map(编码为 h'a0'). 零长度 byte string 编码是首选, 因为它更短, 且是 cryptographic computation 的 serialization structures 中使用的版本. recipient MUST 同时接受零长度 byte string 和编码在 byte string 中的零长度 map.
用 byte string 封装编码后, protected map 在传输中更不容易被意外更改. (行为不当的中间实体可能会 decode 并 re-encode, 但除非重新编码的 byte string 与解码得到的 byte string 完全相同, 否则验证会失败.) 这避免了所有参与方都必须能够对 map 执行共同 canonical encoding, 再将其作为 cryptographic operations 输入的问题.
unprotected: 包含关于当前 layer 且不受密码学保护的 parameters.
只有处理当前 layer 的 header parameters 才放在该 layer. 例如, header parameter "content type" 描述消息中承载的消息内容. 因此, 此 header parameter 只放在 content layer, 而不放在 recipient layer 或 signature layer. 原则上, 应能在不引用任何其他 layer 的情况下处理任意给定 layer. 除 COSE_Sign 结构外, 唯一需要跨 layer 的数据是 cryptographic key.
本文档定义的所有 security objects 中都存在这些 bucket. 字段按顺序为 "protected" bucket(作为 CBOR "bstr" 类型), 然后是 "unprotected" bucket(作为 CBOR "map" 类型). 两个 bucket 都必须存在. 放入 bucket 的 header parameters 来自 IANA "COSE Header Parameters" registry (Section 11.1). 下一节定义了一些 header parameters.
每个 map 中的 labels MUST 唯一. 处理消息时, 如果一个 label 出现多次, 消息 MUST 作为 malformed 被拒绝. 应用程序 SHOULD 验证同一个 label 不会同时出现在 protected 和 unprotected header parameters 中. 如果消息没有作为 malformed 被拒绝, 则属性 MUST 从 protected bucket 获取; 只有当某个属性在 protected bucket 中未找到时, 才能从 unprotected bucket 获取该属性.
以下 CDDL 片段表示这两个 header-parameter bucket. CDDL 中定义了一个 group "Headers", 表示放置 attributes 的两个 bucket. 该 group 用于在所有位置一致地提供这两个字段. 还定义了一个类型, 表示 common header parameters 的 map.
Headers = (
protected : empty_or_serialized_map,
unprotected : header_map
)
header_map = {
Generic_Headers,
* label => values
}
empty_or_serialized_map = bstr .cbor header_map / bstr .size 0
3.1. Common COSE Header Parameters
本节定义一组 common header parameters. 这些 header parameters 的摘要见 Table 3. 应查阅该表来确定 label 的值以及 value 的类型.
本节定义的 header parameters 集合如下:
alg: 此 header parameter 用于指示 security processing 所用的 algorithm. 在具备认证能力时, 此 header parameter MUST 被认证. AEAD algorithms 或构造(例如 COSE_Sign 和 COSE_Mac0)提供这种支持. 该认证可以通过将 header parameter 放入 protected-header-parameters bucket 来完成, 也可以作为 externally supplied data (Section 4.3) 的一部分完成. 其值取自 "COSE Algorithms" registry (见 [COSE.Algorithms]).
crit: 此 header parameter 用于指示处理消息的应用程序必须理解哪些 protected header parameters. 本文档定义的 header parameters 不需要包含在内, 因为所有实现都应理解它们. 此外, 为了与遵循 [RFC8152] 且假定所有实现都理解它的 sender 保持兼容, 新实现必须理解 [RFC8152] 定义的 header parameter "counter signature" (label 7). 当存在时, "crit" header parameter MUST 放在 protected-header-parameters bucket 中. 该 array MUST 至少包含一个值.
并非所有 header-parameter labels 都需要包含在 "crit" header parameter 中. 决定哪些 header parameters 放入该 array 的规则如下:
* 0 到 7 范围内的 integer labels SHOULD 省略.
* -1 到 -128 范围内的 integer labels 可以省略. 当处理 label 内容的能力被认为是实现算法的核心能力时, algorithms 可以在此范围内分配 labels. 当处理 label 内容的能力不被认为是该算法的核心功能, 但确实需要理解它才能正确处理当前实例时, algorithms 可以在此范围外分配 labels 并将其包含在 "crit" header parameter 中. -129 到 -65536 范围内的 integer labels SHOULD 包含在内, 因为这些会是较不常见且可能未被普遍支持的 header parameters.
* 应用所需 header parameters 的 labels MAY 省略. 应用应有一项声明, 说明该 label 是否可以省略.
"crit" 指示的 header parameters 可以由 security-library code 处理, 也可以由使用安全库的应用处理; 唯一要求是该 header parameter 被处理. 如果 "crit" value list 包含某个 label, 但对应 header parameter 不在 protected-header-parameters bucket 中, 则这是消息处理中的 fatal error.
content type: 此 header parameter 用于指示 "payload" 或 "ciphertext" 字段中数据的 content type. integer 来自 "CoAP Content-Formats" IANA registry table [COAP.Formats]. text 值遵循 "<type-name>/<subtype-name>" 语法, 其中 <type-name> 和 <subtype-name> 定义于 [RFC6838] Section 4.2. 不允许前导或尾随 whitespace. 文本 content type 值及其 parameters 和 subparameters 可通过 IANA "Media Types" registry 查找. 如果 content structure 可能存在歧义, 应用程序 SHOULD 提供此 header parameter.
kid: 此 header parameter 标识一段可作为输入来查找所需 cryptographic key 的数据. 此 header parameter 的值可与 COSE_Key 结构中的 "kid" member 匹配. 其他 key distribution 方法可以定义要匹配的等价字段. 应用程序 MUST NOT 假定 "kid" 值唯一. 可能存在多个具有相同 "kid" 值的 key, 因此可能需要检查与该 "kid" 关联的所有 key. "kid" 值的内部结构未定义, 应用程序不能依赖它. Key identifier 值只是关于使用哪个 key 的提示. 这不是 security-critical 字段. 因此, 它可以放在 unprotected-header-parameters bucket 中.
IV: 此 header parameter 保存 Initialization Vector (IV) 值. 对某些 symmetric encryption algorithms, 这也可以称为 nonce. IV 可以放在 unprotected bucket 中, 因为对 AE 和 AEAD algorithms 而言, 修改 IV 将导致 decryption 失败.
Partial IV: 此 header parameter 保存 IV 值的一部分. 使用 COSE_Encrypt0 结构时, IV 的一部分可以属于与 key 关联的上下文(Context IV), 另一部分可随每条消息改变(Partial IV). 此字段用于承载一个值, 使 IV 对每条消息发生改变. Partial IV 可以放在 unprotected bucket 中, 因为修改该值会导致 decryption 产生很容易检测为乱码的 plaintext. "Initialization Vector" 和 "Partial Initialization Vector" header parameters MUST NOT 同时存在于同一个 security layer 中.
message IV 通过以下步骤生成:
1. 将 Partial IV 左侧填充零, 直到达到 IV 的长度(由算法确定).
2. 将填充后的 Partial IV 与 Context IV 执行 XOR.
+=========+=======+========+=====================+==================+ | Name | Label | Value | Value Registry | Description | | | | Type | | | +=========+=======+========+=====================+==================+ | alg | 1 | int / | COSE Algorithms | 要使用的 | | | | tstr | registry | cryptographic | | | | | | algorithm | +---------+-------+--------+---------------------+------------------+ | crit | 2 | [+ | COSE Header | 必须理解的 | | | | label] | Parameters | critical header | | | | | registry | parameters | +---------+-------+--------+---------------------+------------------+ | content | 3 | tstr / | CoAP Content- | payload 的 | | type | | uint | Formats or Media | content type | | | | | Types registries | | +---------+-------+--------+---------------------+------------------+ | kid | 4 | bstr | | Key identifier | +---------+-------+--------+---------------------+------------------+ | IV | 5 | bstr | | 完整 | | | | | | Initialization | | | | | | Vector | +---------+-------+--------+---------------------+------------------+ | Partial | 6 | bstr | | Partial | | IV | | | | Initialization | | | | | | Vector | +---------+-------+--------+---------------------+------------------+
Table 3: Common Header Parameters
表示本节定义的 header parameters 集合的 CDDL 片段如下. 每个 header parameter 都标记为 optional, 因为它们不需要出现在每个 map 中; 特定 map 中需要的 header parameters 已在上文讨论.
Generic_Headers = ( ? 1 => int / tstr, ; algorithm identifier ? 2 => [+label], ; criticality ? 3 => tstr / int, ; content type ? 4 => bstr, ; key identifier ? ( 5 => bstr // ; IV 6 => bstr ) ; Partial IV )