MPPE-从 MS-CHAPv2 发送和接收密钥派生

信息安全 加密 验证 视窗 密钥生成 半径
2021-09-04 13:42:47

我正在尝试从 MS-CHAPv2 挑战材料中获取 MS-MPPE-Send-key 和 MS-MPPE-Recv-key。我可以按照 RFC 2548 30783079来获得GetNewKeyFromSHA()它的长度为 16 个字节。

我可以使用密钥来加密数据,例如3079中的示例。问题是我不确定我应该如何获取 RFC 2548中使用的会话密钥以从那里获取 MS-MPPE-Send-key 和 MS-MPPE-Recv-key 字段。

我有一个 freeradius 的示例,会话密钥在构造 RFC 2548中所述的字符串之前从 16 字节长转换为 32 字节长

之后我尝试使用 RC4 加密会话密钥,GetNewKeyFromSHA()但它对我不起作用。如果有人能详细解释一下这个中间步骤,那就太好了!

编辑 1

我也尝试过两次在2548中进行加密,但仍然没有结果,我现在正在研究 freeRADIUS 源代码,但在从 MS-CHAPv2 材料中获取主密钥后并不容易理解。有任何想法吗?

编辑 2

查看 freeradius 似乎是首先它从 MS-CHAv2 材料中派生密钥,然后不是加密发送它们,而是使用主密钥和来自 TLS 握手的随机数来生成 32 字节的发送和接收密钥. 正如 RFC 2716所说,然后将它们加密为 RFC 2548,最后发送它们。

那么是否可以像在 RFC 3079中那样使用从 MS-CHAPv2 材料派生的主密钥?或者这样做的唯一方法是freeradius吗?

1个回答

不确定您的问题,这些值是如何加密的?它在RFC-2548 第 2.4.2 节中进行了描述。

我认为这是因为在你的问题中你说:

我有一个 freeradius 的示例,会话密钥在构造 RFC 2548 中所述的字符串之前从 16 个字节长转换为 32 个字节长。

所以您想知道如何从 16 字节密钥变为 RADIUS 属性中使用的 32 字节值?

基本上,您的 32 字节密钥是 16 字节密钥的 2 个连接的 MD5 哈希。因此,该值必须是 16 的倍数。您拥有 32 而不是 16 的原因是您将单字节值16(用于键长度)添加到使长度为 17 的键值上,从而将其推入第二个 16 字节窗口。剩余的 15 个字节应该用 0 填充。

因此,无论如何,您正在使用 RADIUS 共享密钥、来自原始 RADIUS 请求的 16 字节请求身份验证器和随机的 2 字节盐值来加密您现在的 17 字节密钥值。

随机盐值实际上可以是任何东西。正如您所指出的那样,freeradius 是从 TLS 函数派生出来的,但这仅适用于您真正通过 TLS 进行隧道传输的情况。你可以从空中拉出一些东西。

然后你将两个字节的盐值添加到你的 32 字节加密值上,生成一个 34 字节的值,你就完成了!

     Construct a plaintext version of the String field by concate-
     nating the Key-Length and Key sub-fields.  If necessary, pad
     the resulting string until its length (in octets) is an even
     multiple of 16.  It is recommended that zero octets (0x00) be
     used for padding.  Call this plaintext P.

     Call the shared secret S, the pseudo-random 128-bit Request
     Authenticator (from the corresponding Access-Request packet) R,
     and the contents of the Salt field A.  Break P into 16 octet
     chunks p(1), p(2)...p(i), where i = len(P)/16.  Call the
     ciphertext blocks c(1), c(2)...c(i) and the final ciphertext C.
     Intermediate values b(1), b(2)...c(i) are required.  Encryption
     is performed in the following manner ('+' indicates
     concatenation):

  b(1) = MD5(S + R + A)    c(1) = p(1) xor b(1)   C = c(1)
  b(2) = MD5(S + c(1))     c(2) = p(2) xor b(2)   C = C + c(2)
              .                      .
              .                      .
              .                      .
  b(i) = MD5(S + c(i-1))   c(i) = p(i) xor b(i)   C = C + c(i)

  The   resulting   encrypted   String   field    will    contain
  c(1)+c(2)+...+c(i).