C# RADIUS和EAP计算消息验证器

C# RADIUS和EAP计算消息验证器,c#,hmac,radius,C#,Hmac,Radius,我一直在阅读RFC3579,因为我正在实现一个支持EAP-MD5身份验证的RADIUS服务。不幸的是,我有点不确定如何解释RFC,特别是在试图计算消息验证器时 我基本上创建了一个HMAC-MD5对象(我使用的是C#),使用NAS的共享机密作为密钥,并连接类型(一个字节)+标识符(一个字节)+长度(两个字节)+请求验证器(16字节)+所有属性(除了访问请求中的消息验证器)但计算值与数据包中的值不匹配 在RFC之后,这似乎是正确的。我对RFC的解释正确吗 代码如下: RadiusPacket pac

我一直在阅读RFC3579,因为我正在实现一个支持EAP-MD5身份验证的RADIUS服务。不幸的是,我有点不确定如何解释RFC,特别是在试图计算消息验证器时

我基本上创建了一个HMAC-MD5对象(我使用的是C#),使用NAS的共享机密作为密钥,并连接类型(一个字节)+标识符(一个字节)+长度(两个字节)+请求验证器(16字节)+所有属性(除了访问请求中的消息验证器)但计算值与数据包中的值不匹配

在RFC之后,这似乎是正确的。我对RFC的解释正确吗

代码如下:

RadiusPacket packet = Objects.Packet;

byte[] toHMAC;
toHMAC = new byte[1] { (byte)packet.Code };
toHMAC = ByteArray.Combine(toHMAC, new byte[1] { packet.Identifier });
// reversed to match endian of packet
toHMAC = ByteArray.Combine(toHMAC, ByteArray.Reverse(packet.LengthAsBytes));
toHMAC = ByteArray.Combine(toHMAC, packet.Authenticator);

for (int i = 0; i < packet.Attributes.Length; i++)
{
    if (packet.Attributes[i].Type != RadiusAttributeType.MessageAuthenticator)
    {
        toHMAC = ByteArray.Combine(toHMAC, packet.Attributes[i].RawData);
    }
}

HMACMD5 md5 = new HMACMD5(Encoding.ASCII.GetBytes(Objects.NAS.SharedSecret));

// this DOES NOT match what is in the received packet...
byte[] hmac = md5.ComputeHash(toHMAC);
RadiusPacket-packet=Objects.packet;
字节[]toHMAC;
toHMAC=新字节[1]{(字节)packet.Code};
toHMAC=ByteArray.Combine(toHMAC,新字节[1]{packet.Identifier});
//反转以匹配数据包的尾端
toHMAC=ByteArray.Combine(toHMAC,ByteArray.Reverse(packet.LengthAsBytes));
toHMAC=ByteArray.Combine(toHMAC,packet.Authenticator);
for(int i=0;i

任何帮助都将不胜感激。

我通过重新阅读RFC和查看JQuery中的一些源代码找到了答案。这是我为其他有同样经历的人所发现的

RFC(3579)内容如下:

'计算消息完整性检查时,签名字符串应视为十六个八位字节的零。'

收到访问请求数据包后,我用16个零字节替换现有的消息验证器,然后HMAC-MD5替换整个数据包,并将计算值与数据包中的消息验证器进行比较

代码要简单得多(我从wireshark捕获中创建了一个测试包):


您的代码很接近,但不完全相同。您正在完全剥离
消息验证器
属性

相反,它应该保持在数据包中的原始位置,但是该属性的16字节
字段应该用零覆盖

// a radius-eap packet captured from wireshark
RadiusPacket packet = new RadiusPacket(ByteArray.FromHex("017600ad375be8f596e90bcffc5e32929d14275b04060a3e01ee05060000c3513d060000000f011f686f73742f64727377696e377472616379702e6472736c2e636f2e756b1e1330302d31322d30302d45332d34312d43311f1342342d39392d42412d46322d38412d44360606000000020c06000005dc4f240200002201686f73742f64727377696e377472616379702e6472736c2e636f2e756b5012c93ef628690a578b31709b0bbccade41"));

// identical packet that I can zero out MA for testing
RadiusPacket radiusPacketCopy = new RadiusPacket(ByteArray.FromHex("017600ad375be8f596e90bcffc5e32929d14275b04060a3e01ee05060000c3513d060000000f011f686f73742f64727377696e377472616379702e6472736c2e636f2e756b1e1330302d31322d30302d45332d34312d43311f1342342d39392d42412d46322d38412d44360606000000020c06000005dc4f240200002201686f73742f64727377696e377472616379702e6472736c2e636f2e756b5012c93ef628690a578b31709b0bbccade41"));

// zero out MA
radiusPacketCopy.ZeroMessageAuthenticator();

// hash it up
HMACMD5 md5 = new HMACMD5(Encoding.ASCII.GetBytes("mykey"));
byte[] hmac = md5.ComputeHash(radiusPacketCopy.RawPacket);

// the message authenticator MUST be correct
if (!ByteArray.AreEqual(hmac, packet.MessageAuthenticator))
{
    // etc