过去我已经实现了自己的 v1/v2 SNMP 管理器。现在我还想支持 v3,因此必须实现 PDU 的加密。根据RFC2274 第 8.1.1.1 章16 字节私有密钥的前 8 个字节代表 DES 密钥,私有密钥的后 8 个字节代表 Prev InitVector...执行 PDU 的 CBC-DES 加密所需的两个值。
现在我的问题是:大多数 SNMP v3 管理工具,例如Paessler SNMP 测试仪期望用户在输入时(至少)提供一个 8 字节长的 V3 加密密钥。我认为这个V3加密密钥必须覆盖完整的16字节私有密钥信息,因为不能传递与加密相关的其他信息。这些工具如何在内部从这个短的 8 字节 V3 加密密钥中计算 DES 密钥和 Prev InitVector?
我已经完成的测试:
- 我使用 8 字节长的 V3 加密密钥作为 DES 密钥,并假设 PrevIV 为 0000 0000
- 我使用 8 字节长的 V3 加密密钥作为 DES 密钥,也作为 PrevIV
-> 我根据中描述的算法在代码中加密了 PDURFC2274 第 8.1.1.1 章与我用 Wireshark 读出的 Paessler 加密 PDU 相比,结果总是完全不同。 (对于这个测试,我使用了与 Paessler 相同的 PDU 和盐,我通过 Wireshark 在 privParameters 字段中读出了它们)
请不要讨论 CBC-DES 是否安全,谢谢! ;-)
您缺少的部分是关键本地化步骤。您提到的“加密密钥”更准确地称为“共享秘密”(RFC 通常将其称为“密码”)。为了与 SNMP 引擎通信,您必须通过将共享密钥与权威引擎 ID 相结合来生成“本地化密钥”(在两个引擎之间的每次交互中,其中一个是权威的 - 您可以在RFC 3414 第 2.1 节)。关键定位算法描述于RFC 3414 第 2.6 节。解释的不是很清楚,所以我尝试总结一下。
本地化算法的第一步是从密码生成中间密钥。创建长度为 1048576 的缓冲区(2^20
)并通过一遍又一遍地重复密码来填充它(如果需要,截断密码的最后一个副本)。然后使用用户的身份验证协议计算缓冲区的哈希值。 (好吧,所以您实际上不必创建该大小的缓冲区,您可以一次对一个块进行哈希处理 - 详细信息取决于哈希算法的实现)。
计算出 Ku 后,计算哈希值Ku + engineID + Ku
(where +
代表连接)。This生成“本地化”密钥(称为“Kul”——我猜“l”的意思是“本地化”),然后将其截断为 16 字节(如果需要),并拆分为 8 字节 DES 密钥(其中仅实际使用了7个字节),以及8个字节的pre-IV。
附录A.3提供示例密码和引擎 ID,以及具有 HMAC-MD5 和 HMAC-SHA 的预期 Ku 和 Kul。下面是一些在 Python 中执行这些示例输入的关键本地化的代码,使用python-snmp
图书馆 (pip install snmp==0.5.0
):
from snmp.security.usm.auth import *
secret = b"maplesyrup"
engineID = bytes.fromhex("00 00 00 00 00 00 00 00 00 00 00 02")
Ku = HmacMd5.computeKey(secret)
Kul = HmacMd5.localizeKey(Ku, engineID)
print(f"MD5 Ku: {Ku.hex()}")
print(f"MD5 Kul: {Kul.hex()}")
Ku = HmacSha.computeKey(secret)
Kul = HmacSha.localizeKey(Ku, engineID)
print(f"SHA Ku: {Ku.hex()}")
print(f"SHA Kul: {Kul.hex()}")
这给出了每个示例的预期键:
MD5 Ku: 9faf3283884e92834ebc9847d8edd963
MD5 Kul: 526f5eed9fcce26f8964c2930787d82b
SHA Ku: 9fb5cc0381497b3793528939ff788d5d79145211
SHA Kul: 6695febc9288e36282235fc7151f128497b38f3f
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)