目录

简介

身份验证器报头

响应的身份验证

何时应该预期验证失败？

密码隐藏

重新传输

记账

消息验证器属性

何时应使用消息验证器？

何时应该预期验证失败？

验证消息验证器属性

相关信息

简介

本文档介绍两种RADIUS安全机制：

- 身份验证器报头

- 消息验证器属性

本文档介绍这些安全机制是什么、它们的使用方式，以及您预计何时会出现验证失败。

身份验证器报头

根据RFC 2865，身份验证器报头长度为16字节。在访问请求中使用时，它称为请求验证器。当它用于任何类型的响应时，它称为响应验证器。它用于：

- 响应的身份验证

- 密码隐藏

响应的身份验证

如果服务器使用正确的响应身份验证器进行响应，客户端可以计算该响应是否与有效请求相关。

客户端发送带有随机身份验证器报头的请求。然后，发送响应的服务器会使用请求数据包和共享密钥计算响应身份验证器：

ResponseAuth = MD5(Code + ID + Length + RequestAuth + Attributes + Secret)

接收响应的客户端执行相同的操作。如果结果相同，则数据包正确。

注意：知道密钥值的攻击者无法欺骗响应，除非它能够嗅探到请求。

何时应该预期验证失败？

如果交换机不再缓存请求（例如，由于超时），则会发生验证失败。 当共享密钥无效（是 — Access-Reject也包含此报头）时，您也可能会遇到此问题。 这样，网络接入设备(NAD)可以检测共享密钥不匹配。通常，身份验证、授权和记帐(AAA)客户端/服务器会将其报告为共享密钥不匹配，但不会显示详细信息。

密码隐藏

身份验证器报头也用于避免以纯文本形式发送用户密码属性。首先计算消息摘要5（MD5 — 加密，验证器）。然后，对密码块执行多个XOR操作。由于MD5不再被视为强单向算法，因此此方法很容易受到离线攻击（彩虹表）。

以下是计算用户密码的Python脚本：

def Encrypt_Pass(password, authenticator, secret):

m = md5()

m.update(secret+authenticator)

return "".join(chr(ord(x) ^ ord(y)) for x, y in zip(password.ljust

(16,'\0')[:16], m.digest()[:16]))

重新传输

如果RADIUS访问请求中的任何属性已更改（如RADIUS ID、用户名等），应生成新的身份验证器字段，并重新计算所有依赖它的其他字段。如果这是重新传输，则不应有任何变化。

记账

身份验证器报头对于访问请求和记帐请求的含义不同。

对于访问请求，身份验证器是随机生成的，预期会收到响应，响应身份验证器计算正确，这证明响应与该特定请求相关。

对于记帐请求，身份验证器不是随机的，但是它是按照RFC 2866计算的：

RequestAuth = MD5(Code + ID + Length + 16 zero octets + Attributes + Secret)

这样，如果重新计算的值与验证器值不匹配，服务器可以立即检查记帐消息并丢弃数据包。身份服务引擎(ISE)返回：

11038 RADIUS Accounting-Request header contains invalid Authenticator field

出现这种情况的典型原因是共享密钥不正确。

消息验证器属性

消息验证器属性是RFC 3579中定义的RADIUS属性。其用途类似：签名和验证。但这次，它不用于验证响应，而用于验证请求。

发送访问请求的客户端（也可以是以访问质询作出响应的服务器）从自己的数据包计算基于哈希的消息身份验证代码(HMAC)-MD5，然后添加消息身份验证器属性作为签名。然后，服务器可以验证它执行了相同的操作。

公式类似于验证器报头：

Message-Authenticator = HMAC-MD5 (Type, Identifier, Length, Request Authenticator,

Attributes)

HMAC-MD5函数包含两个参数：

- 数据包的负载，包括16字节的Message-Authenticator字段，填入零

- 共享密钥

何时应使用消息验证器？

每个数据包必须使用消息验证器，包括可扩展身份验证协议(EAP)消息(RFC 3579)。 这包括发送Access-Request的客户端和以Access-Challenge响应的服务器。如果验证失败，另一端应以静默方式丢弃数据包。

何时应该预期验证失败？

当共享密钥无效时，验证失败。然后，AAA服务器无法验证请求。

ISE报告：

11036 The Message-Authenticator Radius Attribute is invalid.

这通常发生在EAP消息附加的后期。802.1x会话的第一个RADIUS数据包不包含EAP消息；没有消息验证器字段，无法验证请求，但在该阶段，客户端能够使用验证器字段验证响应。

验证消息验证器属性

以下示例说明如何手动计数值，以确保其计算正确。

已选择数据包编号30（访问请求）。它处于EAP会话中，且数据包包含Message-Authenticator字段。目的是验证消息验证器是否正确：

1. 右键单击Radius Protocol并选择Export Selected packet bytes。

2. 将该RADIUS负载写入文件（二进制数据）。

3. 要计算消息验证器字段，必须将零置于此处并计算HMAC-MD5。

例如，当您使用十六进制/二进制编辑器（如vim）时，在键入“：%!xxd”后，它会切换到十六进制模式，从“5012”后开始为16个字节(50hex是80，其中是消息验证器类型，12是18，包括属性值对(AVP)报头):

修改后，负载就绪。必须返回十六进制/二进制模式(类型：":%!xxd -r")并保存文件(":wq")。

4. 使用OpenSSL计算HMAC-MD5:

pluton # cat packet30-clear-msgauth.bin | openssl dgst -md5 -hmac 'cisco'

(stdin)= 01418d3b1865556918269d3cf73608b0
HMAD-MD5函数采用两个参数：第一个来自标准输入(stdin)是消息本身，第二个是共享密钥（本例中为思科）。 结果与附加到RADIUS Access-Request数据包的消息验证器的值完全相同。

使用Python脚本可以计算相同值：

pluton # cat hmac.py

#!/usr/bin/env python

import base64

import hmac

import hashlib

f = open('packet30-clear-msgauth.bin', 'rb')

try:

body = f.read()

finally:

f.close()

digest = hmac.new('cisco', body, hashlib.md5)

d=digest.hexdigest()

print d

pluton # python hmac.py

01418d3b1865556918269d3cf73608b0

上一个示例介绍如何从Access-Request计算Message-Authenticator字段。对于Access-Challenge、Access-Accept和Access-Reject，逻辑完全相同，但务必记住应使用请求身份验证器，这在以前的Access-Request数据包中提供。

相关信息

- RFC 2865

- RFC 2866

- RFC 3579

- 技术支持和文档 - Cisco Systems