4. 内容加密算法
- 内容加密算法
[RFC9052] 第 8.3 节包含对 content encryption algorithms 的通用描述. 本文档定义三种 content encryption algorithms 的 identifier 和用法.
4.1. AES-GCM
Galois/Counter Mode (GCM) mode 是 [AES-GCM] 中定义的通用 AEAD block cipher mode. GCM mode 与 AES block encryption algorithm 结合, 定义 AEAD cipher.
GCM mode 由 authentication tag 的大小和 nonce 的大小参数化. 本文档将 nonce 大小固定为 96 位. authentication tag 的大小限制在一小组值内. 然而, 对于本文档, authentication tag 的大小固定为 128 位.
本文档定义的算法集合见表 5.
+=========+=======+==========================================+
| Name | Value | Description |
+=========+=======+==========================================+
| A128GCM | 1 | AES-GCM mode w/ 128-bit key, 128-bit tag |
+---------+-------+------------------------------------------+
| A192GCM | 2 | AES-GCM mode w/ 192-bit key, 128-bit tag |
+---------+-------+------------------------------------------+
| A256GCM | 3 | AES-GCM mode w/ 256-bit key, 128-bit tag |
+---------+-------+------------------------------------------+
表 5: AES-GCM 的 Algorithm Values
Key 可以从 key structure 或 recipient structure 获得. 执行加密或解密的实现 MUST 验证 key type, key length 和 algorithm 对相关实体而言正确且适当.
对此算法使用 COSE key 时, 执行以下检查:
-
"kty" 字段 MUST 存在, 且 MUST 为 "Symmetric".
-
如果 "alg" 字段存在, 它 MUST 匹配正在使用的 AES-GCM algorithm.
-
如果 "key_ops" 字段存在, 加密时它 MUST 包含 "encrypt" 或 "wrap key".
-
如果 "key_ops" 字段存在, 解密时它 MUST 包含 "decrypt" 或 "unwrap key".
4.1.1. AES-GCM 的安全考量
使用 AES-GCM 时, MUST 强制执行以下限制:
-
对于每条被加密消息, key 和 nonce pair MUST 唯一.
-
对单个 key 加密的消息总数 MUST NOT 超过 2^32 [SP800-38D]. 只有在预期可能超过此限制的环境中, 才需要显式检查.
-
[RFC8446] 包含对其环境中使用 AES-CGM 的分析. 基于该建议, 应将加密消息数量限制为 2^24.5.
-
[ROBUST] 中较新的分析表明, 确定何时执行 key rollover 时需要把失败解密次数纳入考虑. 按照 DTLS 中的建议 ([RFC9147] 第 4.5.3 节), 失败消息解密次数应限制为 2^36.
曾考虑支持更小的 tag 值; 受限环境社区希望 tag size 位于 64 位范围. 这种用法会显著改变最大消息大小 (通常不是问题) 和 key 可使用次数. 鉴于 Counter with CBC-MAC (CCM) 是受限环境的常用模式, 因此不支持受限模式.
4.2. AES-CCM
CCM 是 [RFC3610] 中定义的通用 authentication encryption block cipher mode. CCM mode 与 AES block encryption algorithm 结合, 定义在受限设备中常用的 AEAD cipher.
CCM mode 有两个参数选择. 第一个选择是 M, 即 authentication field 的大小. M 值的选择涉及消息增长 (来自 tag) 与攻击者能够不可检测地修改消息的概率之间的权衡. 第二个选择是 L, 即 length field 的大小. 该值需要在最大消息大小和 nonce 大小之间权衡.
遗憾的是, CCM 规范把 L 和 M 指定为字节计数而不是比特计数. 这会导致可能的误解, 例如 AES-CCM-8 经常用于指代 authentication 大小为 64 位而不是 8 位的 CCM mode 版本. 在大多数加密算法规范中, 这些值传统上指定为比特计数而不是字节计数. 本文档将遵循使用比特计数的约定, 以便更容易比较本文档给出的不同算法.
本文档基于 L 和 M 的值定义算法矩阵. 受限设备通常运行在使用短消息且希望避免执行 recipient-specific 加密操作的情形中. 这有利于使用较小的 L 和 M 值. 受限较少的设备会希望能够使用更大的消息, 并且更愿意为每次操作生成新 key. 这有利于使用较大的 L 和 M 值.
L 使用以下值:
16 bits (2): 这将消息长度限制为 2^16 字节 (64 KiB). 对受限环境中的消息而言, 这已经足够长. nonce 长度为 13 字节, 允许 2^104 个可能的 nonce 值而不重复.
64 bits (8): 这将消息长度限制为 2^64 字节. nonce 长度为 7 字节, 允许 2^56 个可能的 nonce 值而不重复.
M 使用以下值:
64 bits (8): 这会产生 64-bit authentication tag. 这意味着被修改消息通过认证的概率为 1/2^64.
128 bits (16): 这会产生 128-bit authentication tag. 这意味着被修改消息通过认证的概率为 1/2^128.
+====================+=======+====+=====+========+===============+
| Name | Value | L | M | Key | Description |
| | | | | Length | |
+====================+=======+====+=====+========+===============+
| AES-CCM-16-64-128 | 10 | 16 | 64 | 128 | AES-CCM mode |
| | | | | | 128-bit key, |
| | | | | | 64-bit tag, |
| | | | | | 13-byte nonce |
+--------------------+-------+----+-----+--------+---------------+
| AES-CCM-16-64-256 | 11 | 16 | 64 | 256 | AES-CCM mode |
| | | | | | 256-bit key, |
| | | | | | 64-bit tag, |
| | | | | | 13-byte nonce |
+--------------------+-------+----+-----+--------+---------------+
| AES-CCM-64-64-128 | 12 | 64 | 64 | 128 | AES-CCM mode |
| | | | | | 128-bit key, |
| | | | | | 64-bit tag, |
| | | | | | 7-byte nonce |
+--------------------+-------+----+-----+--------+---------------+
| AES-CCM-64-64-256 | 13 | 64 | 64 | 256 | AES-CCM mode |
| | | | | | 256-bit key, |
| | | | | | 64-bit tag, |
| | | | | | 7-byte nonce |
+--------------------+-------+----+-----+--------+---------------+
| AES-CCM-16-128-128 | 30 | 16 | 128 | 128 | AES-CCM mode |
| | | | | | 128-bit key, |
| | | | | | 128-bit tag, |
| | | | | | 13-byte nonce |
+--------------------+-------+----+-----+--------+---------------+
| AES-CCM-16-128-256 | 31 | 16 | 128 | 256 | AES-CCM mode |
| | | | | | 256-bit key, |
| | | | | | 128-bit tag, |
| | | | | | 13-byte nonce |
+--------------------+-------+----+-----+--------+---------------+
| AES-CCM-64-128-128 | 32 | 64 | 128 | 128 | AES-CCM mode |
| | | | | | 128-bit key, |
| | | | | | 128-bit tag, |
| | | | | | 7-byte nonce |
+--------------------+-------+----+-----+--------+---------------+
| AES-CCM-64-128-256 | 33 | 64 | 128 | 256 | AES-CCM mode |
| | | | | | 256-bit key, |
| | | | | | 128-bit tag, |
| | | | | | 7-byte nonce |
+--------------------+-------+----+-----+--------+---------------+
表 6: AES-CCM 的 Algorithm Values
Key 可以从 key structure 或 recipient structure 获得. 执行加密或解密的实现 MUST 验证 key type, key length 和 algorithm 对相关实体而言正确且适当.
对此算法使用 COSE key 时, 执行以下检查:
-
"kty" 字段 MUST 存在, 且 MUST 为 "Symmetric".
-
如果 "alg" 字段存在, 它 MUST 匹配正在使用的 AES-CCM algorithm.
-
如果 "key_ops" 字段存在, 加密时它 MUST 包含 "encrypt" 或 "wrap key".
-
如果 "key_ops" 字段存在, 解密时它 MUST 包含 "decrypt" 或 "unwrap key".
4.2.1. AES-CCM 的安全考量
使用 AES-CCM 时, MUST 强制执行以下限制:
-
对于每条被加密消息, key 和 nonce pair MUST 唯一. 注意, L 的值会影响唯一 nonce 的数量.
-
AES block cipher 的总使用次数 MUST NOT 超过 2^61 次操作. 此限制是 block cipher 用于计算 MAC 值和执行 stream encryption 操作的次数之和. 只有在预期可能超过此限制的环境中, 才需要显式检查.
-
[RFC9147] 包含对其环境中使用 AES-CCM 的分析. 基于该建议, 应将加密消息数量限制为 2^23.
-
除成功解密的消息数量外, 还需要跟踪失败解密次数. 按照 DTLS 中的建议 ([RFC9147] 第 4.5.3 节), 失败消息解密次数应限制为 2^23.5. 如果使用 64-bit tag, 则在希望保持相同完整性限制时, 限制会显著更小. 推荐这种做法的协议需要分析较小 tag size 可接受的完整性级别. 为保持所需完整性级别, 可能需要频繁到每 2^7 条消息就 rekey.
[RFC3610] 还指出另一个值得注意的考量. 在 plaintext 的部分内容高度可预测的情况下, 可以对该算法执行预计算攻击. 这会把 key size 的安全性降低一半. 处理这种攻击的方法包括向 nonce 值添加随机部分和/或增加所用 key size. 使用 nonce 的一部分作为随机值会减少单个 key 可用于的消息数量. 增加 key size 可能要求受限设备提供更多资源. 更多信息见 [RFC3610] 第 5 和第 10 节.
4.3. ChaCha20 and Poly1305
ChaCha20 和 Poly1305 组合在一起构成 [RFC8439] 中定义的 AEAD mode. 该算法使用非 AES cipher 定义, 因而不会受到未来在 AES 中发现的任何弱点影响. 这些加密函数设计为在纯软件实现中快速运行.
[RFC8439] 中定义的 ChaCha20/Poly1305 AEAD 构造没有参数化. 它以 256-bit key, 96-bit nonce, plaintext 和 additional data 作为输入, 并产生 ciphertext 作为输出. 我们在表 7 中为此算法定义一个 algorithm identifier.
+===================+=======+==========================+
| Name | Value | Description |
+===================+=======+==========================+
| ChaCha20/Poly1305 | 24 | ChaCha20/Poly1305 w/ |
| | | 256-bit key, 128-bit tag |
+-------------------+-------+--------------------------+
表 7: ChaCha20/Poly1305 的 Algorithm Value
Key 可以从 key structure 或 recipient structure 获得. 执行加密或解密的实现 MUST 验证 key type, key length 和 algorithm 对相关实体而言正确且适当.
对此算法使用 COSE key 时, 执行以下检查:
-
"kty" 字段 MUST 存在, 且 MUST 为 "Symmetric".
-
如果 "alg" 字段存在, 它 MUST 匹配正在使用的 ChaCha20/Poly1305 algorithm.
-
如果 "key_ops" 字段存在, 加密时它 MUST 包含 "encrypt" 或 "wrap key".
-
如果 "key_ops" 字段存在, 解密时它 MUST 包含 "decrypt" 或 "unwrap key".
4.3.1. ChaCha20/Poly1305 的安全考量
对算法的每次调用, key 和 nonce 值 MUST 构成唯一 pair. nonce counter 被认为是确保其唯一性的可接受方式.
[ROBUST] 中较新的分析表明, 确定何时执行 key rollover 时需要把失败解密次数纳入考虑. 按照 DTLS 中的建议 ([RFC9147] 第 4.5.3 节), 失败消息解密次数应限制为 2^36.
[RFC8446] 指出, 对 ChaCha20/Poly1305 而言, (64-bit) record sequence number 会在达到安全限制之前回绕. COSE 实现不应发送超过 2^64 条使用单个 ChaCha20/Poly1305 key 加密的消息.