跳到主要内容

8. CBC-DES Symmetric Encryption Protocol (CBC-DES 对称加密协议)

8. CBC-DES Symmetric Encryption Protocol (CBC-DES 对称加密协议)​

本节描述 CBC-DES 对称加密协议.此协议是为基于用户的安全模型定义的第一个隐私协议.

此协议由 usmDESPrivProtocol 标识.

随着时间的推移, 可能会定义其他隐私协议, 作为此协议的替代或补充.

8.1. Mechanisms (机制)​

CBC-DES 加密协议提供以下机制:

Data Confidentiality Support (数据机密性支持)​

为了支持数据机密性, 需要加密算法.在传输之前加密消息的适当部分.基于用户的安全模型指定 scopedPDU 是需要加密的消息部分.

Secret Value and Timeliness (秘密值和时效性)​

秘密值与时效性值结合使用以创建加密/解密密钥和初始化向量.秘密值由所有被授权代表相应用户发起消息的 SNMP 引擎共享.

8.1.1. Symmetric Encryption Protocol (对称加密协议)​

本备忘录中定义的对称加密协议为数据机密性提供支持.SNMP 消息的指定部分被加密并作为发送给接收者的消息的一部分包含进去.

两个组织发布了定义 DES 的规范:

  • 美国国家标准与技术研究院 (NIST) DES-NIST
  • 美国国家标准协会 (ANSI) DES-ANSI

每个定义都有相应的操作模式规范 (分别为 DESO-NIST 和 DESO-ANSI).

8.1.1.1. DES key and Initialization Vector (DES 密钥和初始化向量)​

DES Key (DES 密钥)​

16 字节秘密 (私有隐私密钥) 的前 8 个字节用作 DES 密钥.由于 DES 仅使用 56 位, 因此每个字节中的最低有效位被忽略.

Initialization Vector (IV) (初始化向量)​

使用以下过程获取加密的初始化向量:

步骤 1: Pre-IV (预 IV)

16 字节秘密 (私有隐私密钥) 的后 8 个字节用作 pre-IV.

步骤 2: Salt Generation (盐值生成)

为了确保由同一密钥加密的两个不同数据包的 IV 不相同 (即 IV 不重复), 我们需要用每个数据包唯一的内容对 pre-IV 进行"加盐".8 字节字符串用作"盐".

生成 SNMP 引擎的 32 位 snmpEngineBoots 和加密引擎维护的本地 32 位整数的串联输入到"盐"中.32 位整数在启动时初始化为任意值.

步骤 3: Salt Encoding (盐值编码)

32 位 snmpEngineBoots 转换为我们的"盐"的前 4 个字节 (最高有效字节优先).然后将 32 位整数转换为我们的"盐"的后 4 个字节 (最高有效字节优先).

步骤 4: IV Calculation (IV 计算)

然后将得到的"盐"与 pre-IV 进行 XOR 以获得 IV.

步骤 5: privParameters (隐私参数)

然后将 8 字节"盐"编码为 OCTET STRING 放入 privParameters 字段.然后修改"盐"整数.我们建议将其递增 1, 并在达到最大值时回绕.

实现注意事项 (Implementation Note):

"盐"(因此 IV) 的值如何变化是一个实现问题, 只要采取措施避免产生重复的 IV.

"盐"必须放入 privParameters 字段, 以使接收实体能够计算正确的 IV 并解密消息.

8.1.1.2. Data Encryption (数据加密)​

数据加密过程遵循以下步骤:

步骤 1: Padding (填充)​

要加密的数据被视为字节序列.其长度应为 8 的整数倍 - 如果不是, 则根据需要在末尾填充数据.实际填充值无关紧要.

步骤 2: Cipher Block Chaining Mode (密码块链接模式)​

数据以密码块链接模式加密.

步骤 3: Block Processing (块处理)​

明文被分成 64 位块.

每个块的明文与前一个块的密文进行 XOR, 结果被加密, 加密的输出就是该块的密文.重复此过程直到没有更多明文块.

步骤 4: First Block (第一块)​

对于第一个块, 使用初始化向量而不是前一个块的密文.

8.1.1.3. Data Decryption (数据解密)​

数据解密过程遵循以下步骤:

步骤 1: Length Verification (长度验证)​

在解密之前, 验证加密数据长度.如果要解密的 OCTET STRING 的长度不是 8 字节的整数倍, 则停止解密过程并记录适当的异常.解密时, 忽略填充.

步骤 2: First Block Decryption (第一块解密)​

第一个密文块被解密, 解密输出与初始化向量进行 XOR, 结果是第一个明文块.

步骤 3: Subsequent Blocks (后续块)​

对于每个后续块, 密文块被解密, 解密输出与前一个密文块进行 XOR, 结果是明文块.

8.2. Elements of the DES Privacy Protocol (DES 隐私协议的要素)​

本节包含实现本备忘录此节中定义的隐私模块所需的定义.

8.2.1. Users (用户)​

使用此隐私协议的隐私利用一组已定义的 userName.对于在特定 SNMP 引擎上代表其进行消息加密/解密的任何用户, 该 SNMP 引擎必须了解该用户.希望与另一个 SNMP 引擎通信的 SNMP 引擎还必须了解该引擎已知的用户, 包括了解该用户的适用属性.

用户及其属性定义如下:

<userName> (用户名)​

表示用户名称的字符串.

<privKey> (隐私密钥)​

加密/解密消息时要使用的用户秘密密钥.对于 CBC-DES, 它必须为 16 字节长.

8.2.2. msgAuthoritativeEngineID (权威引擎 ID)​

已认证/加密消息中包含的 msgAuthoritativeEngineID 值指定该特定消息的权威 SNMP 引擎 (请参阅 SNMP 架构文档 RFC 3411 中 SnmpEngineID 的定义).

用户的 (私有) 隐私密钥在每个权威 SNMP 引擎上通常是不同的, 因此 snmpEngineID 用于为加密/解密过程选择正确的密钥.

8.2.3. SNMP Messages Using this Privacy Protocol (使用此隐私协议的 SNMP 消息)​

使用此隐私协议的消息携带 msgPrivacyParameters 字段作为 msgSecurityParameters 的一部分.

对于此协议, msgPrivacyParameters 字段是表示第 8.1.1.1 节中描述的"盐"的序列化 OCTET STRING.

8.2.4. Services Provided by the DES Privacy Module (DES 隐私模块提供的服务)​

本节描述当基于用户的安全模块调用 DES 隐私模块请求服务时, DES 隐私模块期望的输入和产生的输出.

8.2.4.1. Services for Encrypting an Outgoing SNMP Message (加密出站 SNMP 消息的服务)​

DES 隐私协议假定 privKey 的选择由调用者完成, 并且调用者传递要使用的秘密密钥.

完成后, 隐私模块返回 statusInformation, 如果加密过程成功, 则返回 encryptedPDU.

抽象服务原语为:

statusInformation =              -- 成功或失败
encryptData(
IN privKey -- 用于加密的秘密密钥
IN dataToEncrypt -- 要加密的 scopedPDU
OUT encryptedData -- 加密的 scopedPDU
OUT privParameters -- 序列化的"盐"值
)

参数 (Parameters):

  • statusInformation: 指示加密过程是否成功.如果不成功, 则指示问题所在.

  • privKey: 加密算法要使用的秘密密钥.此密钥的长度必须为 16 字节.

  • dataToEncrypt: 要加密的 scopedPDU.

  • encryptedData: 输出的加密 scopedPDU.

  • privParameters: 用于此加密的"盐"值, 要在 msgPrivacyParameters 中发送.

8.2.4.2. Services for Decrypting an Incoming SNMP Message (解密传入 SNMP 消息的服务)​

DES 隐私协议假定 privKey 的选择由调用者完成, 并且调用者传递要使用的秘密密钥.

完成后, 隐私模块返回 statusInformation, 如果解密过程成功, 则返回 decryptedPDU.

抽象服务原语为:

statusInformation =              -- 成功或失败
decryptData(
IN privKey -- 用于解密的秘密密钥
IN privParameters -- 在 msgPrivacyParameters 中接收的
IN encryptedData -- 加密的 scopedPDU
OUT decryptedData -- 解密的 scopedPDU
)

参数 (Parameters):

  • statusInformation: 指示解密过程是否成功.如果不成功, 则指示问题所在.

  • privKey: 解密算法要使用的秘密密钥.此密钥的长度必须为 16 字节.

  • privParameters: 在 msgPrivacyParameters 中接收的"盐"值.

  • encryptedData: 要解密的加密 scopedPDU.

  • decryptedData: 输出的解密 scopedPDU.

8.3. Elements of Procedure (过程要素)​

本节描述 CBC-DES 隐私协议的过程.

8.3.1. Processing an Outgoing Message (处理出站消息)​

本节描述 SNMP 引擎在代表用户生成带有隐私 (加密) 的消息时所遵循的过程.

步骤 1: 获取隐私密钥​

获取用户的 16 字节 privKey.

步骤 2: 提取 DES 密钥​

提取前 8 个字节作为 DES 密钥.

步骤 3: 获取 Pre-IV​

提取后 8 个字节作为 pre-IV.

步骤 4: 生成盐值​

使用 snmpEngineBoots 和本地计数器生成 8 字节盐值.

步骤 5: 计算 IV​

将盐值与 pre-IV 进行 XOR 以获得初始化向量.

步骤 6: 填充数据​

如有必要, 填充 scopedPDU 使其成为 8 字节的倍数.

步骤 7: 加密​

使用 DES 密钥和 IV 以 CBC-DES 加密填充后的 scopedPDU.

步骤 8: 设置 privParameters​

将盐值放入 msgPrivacyParameters 字段.

步骤 9: 返回结果​

返回 encryptedPDU 和 privParameters.

8.3.2. Processing an Incoming Message (处理传入消息)​

本节描述 SNMP 引擎在处理带有隐私 (加密) 的消息时所遵循的过程.

步骤 1: 获取隐私密钥​

获取用户的 16 字节 privKey.

步骤 2: 提取 DES 密钥​

提取前 8 个字节作为 DES 密钥.

步骤 3: 获取 Pre-IV​

提取后 8 个字节作为 pre-IV.

步骤 4: 提取盐值​

从 msgPrivacyParameters 提取盐值.

步骤 5: 计算 IV​

将盐值与 pre-IV 进行 XOR 以获得初始化向量.

步骤 6: 验证长度​

验证加密数据长度是 8 字节的倍数.如果不是, 返回错误.

步骤 7: 解密​

使用 DES 密钥和 IV 以 CBC-DES 解密 encryptedPDU.

步骤 8: 删除填充​

从解密的数据中删除任何填充.

步骤 9: 返回结果​

返回解密的 scopedPDU.

Implementation Notes (实现注意事项)​

  1. 密钥长度 (Key Length): privKey 对于 CBC-DES 必须正好为 16 字节

  2. DES 密钥使用 (DES Key Usage): 仅前 8 个字节用作 DES 密钥; 后 8 个字节用于 IV 生成

  3. 盐值唯一性 (Salt Uniqueness): 盐值对于每条消息必须是唯一的, 以确保 IV 唯一性

  4. 填充 (Padding): 实现必须正确处理填充, 确保加密数据始终是 8 字节的倍数

  5. 计数器管理 (Counter Management): 盐值计数器应在启动时初始化并为每条消息递增

Security Considerations (安全考虑)​

  • DES 弃用 (DES Deprecation): 按照现代标准, DES 被认为在加密方面很弱.56 位有效密钥长度容易受到暴力攻击

  • 迁移建议 (Migration Recommendation): 新的实现应考虑使用更强的加密算法, 如 AES

  • IV 唯一性 (IV Uniqueness): 对于同一密钥, IV 绝不能重复, 这一点至关重要.实现必须确保正确的盐值管理

  • 密钥管理 (Key Management): 16 字节 privKey 必须保密并妥善管理

  • CBC 模式 (CBC Mode): 虽然 CBC 模式提供机密性, 但它不提供完整性.隐私协议应始终与认证一起使用