5. 密钥派生函数
- 密钥派生函数 (KDFs)
[RFC9052] 第 8.4 节包含 key derivation functions 的通用描述. 本文档定义单个 context structure 和单个 KDF. 这些元素用于本文档中定义的所有需要 KDF 过程的 recipient algorithms. 这些算法定义于第 6.1.2, 6.3.1 和 6.4.1 节.
5.1. HMAC-Based Extract-and-Expand Key Derivation Function (HKDF)
HKDF key derivation algorithm 定义于 [RFC5869] 和 [HKDF].
HKDF 算法接受以下输入:
secret: 共享的秘密值. Secrets 可以是先前共享的值, 也可以从 Diffie-Hellman (DH) key agreement 等操作派生.
salt: 用于改变生成过程的可选值. salt 值可以是公开的, 也可以是私有的. 如果 salt 是公开的并携带在消息中, 则使用表 9 中定义的 "salt" algorithm header parameter. 虽然 [RFC5869] 建议 salt 长度与底层 hash 值长度相同, 但任何正 salt 长度都会提升安全性, 因为会生成不同 key 值. 该参数通过纳入 key 计算而受到保护, 不需要单独认证. salt 值不需要对每条发送消息都是唯一的.
length: 需要生成的输出字节数.
context information: 描述结果值将在何种上下文中使用的信息. 使该信息特定于 material 将要使用的上下文, 可确保结果 material 始终绑定到该用途. 本文档中的 KDF 使用第 5.2 节定义的 context structure.
PRF: HKDF 算法中要使用的底层 pseudorandom function. PRF 被编码进 HKDF algorithm selection.
HKDF 定义为使用 HMAC 作为底层 PRF. 然而, 可以在相同构造中使用其他函数来提供更适合受限环境的不同 KDF. 具体而言, 可以使用 AES-CBC-MAC 作为 expand 步骤的 PRF, 但不能用于 extract 步骤. 当使用正确长度的良好随机 shared secret 时, 可以跳过 extract 步骤. 对于 AES algorithm 版本, extract 步骤始终被跳过.
如果 secret 不是均匀随机的, 则不能跳过 extract 步骤, 例如当它是 ECDH key agreement 步骤的结果时. 这意味着 AES HKDF 版本不能与 ECDH 一起使用. 如果跳过 extract 步骤, 则 "salt" 值不作为 HKDF 功能的一部分使用.
本文档定义的算法见表 8.
+==============+===================+========================+
| Name | PRF | Description |
+==============+===================+========================+
| HKDF SHA-256 | HMAC with SHA-256 | HKDF using HMAC |
| | | SHA-256 as the PRF |
+--------------+-------------------+------------------------+
| HKDF SHA-512 | HMAC with SHA-512 | HKDF using HMAC |
| | | SHA-512 as the PRF |
+--------------+-------------------+------------------------+
| HKDF AES- | AES-CBC-MAC-128 | HKDF using AES-MAC as |
| MAC-128 | | the PRF w/ 128-bit key |
+--------------+-------------------+------------------------+
| HKDF AES- | AES-CBC-MAC-256 | HKDF using AES-MAC as |
| MAC-256 | | the PRF w/ 256-bit key |
+--------------+-------------------+------------------------+
表 8: HKDF Algorithms
+======+=======+======+============================+=============+
| Name | Label | Type | Algorithm | Description |
+======+=======+======+============================+=============+
| salt | -20 | bstr | direct+HKDF-SHA-256, | Random salt |
| | | | direct+HKDF-SHA-512, | |
| | | | direct+HKDF-AES-128, | |
| | | | direct+HKDF-AES-256, ECDH- | |
| | | | ES+HKDF-256, ECDH-ES+HKDF- | |
| | | | 512, ECDH-SS+HKDF-256, | |
| | | | ECDH-SS+HKDF-512, ECDH- | |
| | | | ES+A128KW, ECDH-ES+A192KW, | |
| | | | ECDH-ES+A256KW, ECDH- | |
| | | | SS+A128KW, ECDH-SS+A192KW, | |
| | | | ECDH-SS+A256KW | |
+------+-------+------+----------------------------+-------------+
表 9: HKDF Algorithm Parameters
5.2. Context Information Structure
context information structure 用于确保派生出的 keying material "绑定" 到交易上下文. 此处使用的 context information structure 基于 [SP800-56A] 中定义的结构. 通过使用 CBOR 编码 context information structure, 我们自动获得与使用 ASN.1 时相同的字段类型和长度分离. 这意味着不需要像 JSON Object Signing and Encryption (JOSE) 所用编码 ([RFC7518] 第 4.6.2 节) 那样为基础元素编码长度.
context information structure 使用 PartyU 和 PartyV 指代执行 key derivation 的双方. 除非应用协议另有定义, 我们将 PartyU 分配给创建消息的实体, 将 PartyV 分配给接收消息的实体. 通过定义这种关联, 每个方向都会派生出不同 key, 因为各方向的 context information 不同.
context structure 由双方实体都知道的信息构建. 这些信息可从多种来源获得:
-
字段可以由应用定义. 这通常用于给各方分配固定名称, 但也可用于 nonce 等其他项目.
-
字段可以由输出用途定义. 示例包括正在生成的 algorithm 和 key size.
-
字段可以由来自消息的参数定义. 我们在表 10 中定义了一组 header parameters, 可用于携带与 context structure 关联的值. 这方面的示例包括 identities 和 nonce 值. 这些 header parameters 设计为放在 recipient structure 的 unprotected bucket 中; 它们不需要位于 protected bucket 中, 因为它们已因包含在 context structure 中而纳入加密计算.
+==========+=======+======+===========================+=============+ | Name | Label | Type | Algorithm | Description | +==========+=======+======+===========================+=============+ | PartyU | -21 | bstr | direct+HKDF-SHA-256, | PartyU | | identity | | | direct+HKDF-SHA-512, | identity | | | | | direct+HKDF-AES-128, | information | | | | | direct+HKDF-AES-256, | | | | | | ECDH-ES+HKDF-256, | | | | | | ECDH-ES+HKDF-512, | | | | | | ECDH-SS+HKDF-256, | | | | | | ECDH-SS+HKDF-512, | | | | | | ECDH-ES+A128KW, | | | | | | ECDH-ES+A192KW, | | | | | | ECDH-ES+A256KW, | | | | | | ECDH-SS+A128KW, | | | | | | ECDH-SS+A192KW, | | | | | | ECDH-SS+A256KW | | +----------+-------+------+---------------------------+-------------+ | PartyU | -22 | bstr | direct+HKDF-SHA-256, | PartyU | | nonce | | / | direct+HKDF-SHA-512, | provided | | | | int | direct+HKDF-AES-128, | nonce | | | | | direct+HKDF-AES-256, | | | | | | ECDH-ES+HKDF-256, | | | | | | ECDH-ES+HKDF-512, | | | | | | ECDH-SS+HKDF-256, | | | | | | ECDH-SS+HKDF-512, | | | | | | ECDH-ES+A128KW, | | | | | | ECDH-ES+A192KW, | | | | | | ECDH-ES+A256KW, | | | | | | ECDH-SS+A128KW, | | | | | | ECDH-SS+A192KW, | | | | | | ECDH-SS+A256KW | | +----------+-------+------+---------------------------+-------------+ | PartyU | -23 | bstr | direct+HKDF-SHA-256, | PartyU | | other | | | direct+HKDF-SHA-512, | other | | | | | direct+HKDF-AES-128, | provided | | | | | direct+HKDF-AES-256, | information | | | | | ECDH-ES+HKDF-256, | | | | | | ECDH-ES+HKDF-512, | | | | | | ECDH-SS+HKDF-256, | | | | | | ECDH-SS+HKDF-512, | | | | | | ECDH-ES+A128KW, | | | | | | ECDH-ES+A192KW, | | | | | | ECDH-ES+A256KW, | | | | | | ECDH-SS+A128KW, | | | | | | ECDH-SS+A192KW, | | | | | | ECDH-SS+A256KW | | +----------+-------+------+---------------------------+-------------+ | PartyV | -24 | bstr | direct+HKDF-SHA-256, | PartyV | | identity | | | direct+HKDF-SHA-512, | identity | | | | | direct+HKDF-AES-128, | information | | | | | direct+HKDF-AES-256, | | | | | | ECDH-ES+HKDF-256, | | | | | | ECDH-ES+HKDF-512, | | | | | | ECDH-SS+HKDF-256, | | | | | | ECDH-SS+HKDF-512, | | | | | | ECDH-ES+A128KW, | | | | | | ECDH-ES+A192KW, | | | | | | ECDH-ES+A256KW, | | | | | | ECDH-SS+A128KW, | | | | | | ECDH-SS+A192KW, | | | | | | ECDH-SS+A256KW | | +----------+-------+------+---------------------------+-------------+ | PartyV | -25 | bstr | direct+HKDF-SHA-256, | PartyV | | nonce | | / | direct+HKDF-SHA-512, | provided | | | | int | direct+HKDF-AES-128, | nonce | | | | | direct+HKDF-AES-256, | | | | | | ECDH-ES+HKDF-256, | | | | | | ECDH-ES+HKDF-512, | | | | | | ECDH-SS+HKDF-256, | | | | | | ECDH-SS+HKDF-512, | | | | | | ECDH-ES+A128KW, | | | | | | ECDH-ES+A192KW, | | | | | | ECDH-ES+A256KW, | | | | | | ECDH-SS+A128KW, | | | | | | ECDH-SS+A192KW, | | | | | | ECDH-SS+A256KW | | +----------+-------+------+---------------------------+-------------+ | PartyV | -26 | bstr | direct+HKDF-SHA-256, | PartyV | | other | | | direct+HKDF-SHA-512, | other | | | | | direct+HKDF-AES-128, | provided | | | | | direct+HKDF-AES-256, | information | | | | | ECDH-ES+HKDF-256, | | | | | | ECDH-ES+HKDF-512, | | | | | | ECDH-SS+HKDF-256, | | | | | | ECDH-SS+HKDF-512, | | | | | | ECDH-ES+A128KW, | | | | | | ECDH-ES+A192KW, | | | | | | ECDH-ES+A256KW, | | | | | | ECDH-SS+A128KW, | | | | | | ECDH-SS+A192KW, | | | | | | ECDH-SS+A256KW | | +----------+-------+------+---------------------------+-------------+
表 10: Context Algorithm Parameters
我们定义一个 CBOR object 来保存 context information. 该 object 称为 COSE_KDF_Context. 该 object 基于 CBOR array 类型. 数组中的字段为:
AlgorithmID: 此字段指示 key material 将用于的算法. 这通常是 key wrap algorithm identifier 或 content encryption algorithm identifier. 其值来自 "COSE Algorithms" 注册表. 此字段要求存在. 该字段存在于 context information 中, 因而即使所有其他 context information 都相同, 每个算法也会生成不同 key. 实践中, 这意味着如果算法 A 被攻破, 从而相对容易找到 key, 为算法 B 派生的 key 也不会与为算法 A 派生的 key 相同.
PartyUInfo: 此字段保存关于 PartyU 的信息. PartyUInfo 编码为 CBOR array. PartyUInfo 的元素按下方给出的顺序编码. PartyUInfo array 的元素为:
identity: 其中包含 PartyU 的 identity information. identity 可以通过两种方式之一分配. 第一, 协议可以基于角色分配 identities. 例如, "client" 和 "server" 角色可分配给协议中的不同实体. 然后每个实体会为其发送或接收的数据使用正确 label. 协议分配 identities 的第二种方式是使用基于命名系统的名称 (即 DNS 或 X.509 名称).
我们定义了一个 algorithm parameter, "PartyU identity", 可用于在消息中携带 identity information. 然而, identity information 通常作为协议的一部分为人所知, 因此可以推断而非显式给出. 如果 identity information 携带在消息中, 应用 SHOULD 有方法验证所提供的 identity information. identity information 不需要指定, 在这种情况下设置为 nil.
nonce: 其中包含 nonce 值. nonce 可以由协议隐式给出, 也可以作为值携带在 unprotected header bucket 中.
我们定义了一个 algorithm parameter, "PartyU nonce", 可用于在消息中携带此值; 然而, nonce 值可由应用确定, 并以不同方式获得.
此选项不需要指定; 如果不需要, 则设置为 nil.
other: 其中包含由协议定义的其他信息. 此选项不需要指定; 如果不需要, 则设置为 nil.
PartyVInfo: 此字段保存关于 PartyV 的信息. 该结构内容与 PartyUInfo 相同, 但用于 PartyV.
SuppPubInfo: 此字段包含双方共同知道的公开信息, 并编码为 CBOR array.
keyDataLength: 设置为所需输出值的比特数. 这种做法意味着, 如果算法 A 可以使用两种不同 key 长度, 为较长 key size 派生的 key 不会把较短 key size 的 key 作为前缀包含在内.
protected: 此字段包含 protected parameter field. 如果 "protected" 字段中没有元素, 则使用零长度 bstr.
other: 此字段用于应用定义的自由形式数据. 例如, 应用可以定义两个不同 byte string 放在此处, 以便为数据流和控制流生成不同 key. 此字段是可选的, 只有在应用为此信息定义结构时才会存在. 定义此字段的应用 SHOULD 使用 CBOR 编码数据, 以便正确包含类型和长度.
SuppPrivInfo: 此字段包含双方共同知道的私有信息. 此类信息的示例是预先存在的 shared secret. (例如, 这可与 ECDH key agreement 结合使用, 以提供辅助 identity proof.) 此字段是可选的, 只有在应用为此信息定义结构时才会存在. 定义此字段的应用 SHOULD 使用 CBOR 编码数据, 以便正确包含类型和长度.
以下 CDDL 片段对应于上述文本.
PartyInfo = ( identity : bstr / nil, nonce : bstr / int / nil, other : bstr / nil )
COSE_KDF_Context = [ AlgorithmID : int / tstr, PartyUInfo : [ PartyInfo ], PartyVInfo : [ PartyInfo ], SuppPubInfo : [ keyDataLength : uint, protected : empty_or_serialized_map, ? other : bstr ], ? SuppPrivInfo : bstr ]