C# HMAC如何为ASP.NETWebAPI工作
刚才正在阅读一篇关于web API的文章,其中包含来自此url的HMAC身份验证 HMAC完全是身份验证类型,还是仅仅是散列技术? 如果是认证类型,那么简单地告诉我为什么它应该被认为是认证类型? 如果可能,有人会简要讨论什么是HMAC身份验证,以及这种类型的身份验证如何适用于web api 我从他们的文章中了解到,服务器和客户端将共享一个公共的C# HMAC如何为ASP.NETWebAPI工作,c#,security,authentication,asp.net-web-api,C#,Security,Authentication,Asp.net Web Api,刚才正在阅读一篇关于web API的文章,其中包含来自此url的HMAC身份验证 HMAC完全是身份验证类型,还是仅仅是散列技术? 如果是认证类型,那么简单地告诉我为什么它应该被认为是认证类型? 如果可能,有人会简要讨论什么是HMAC身份验证,以及这种类型的身份验证如何适用于web api 我从他们的文章中了解到,服务器和客户端将共享一个公共的密钥,当客户端请求web api服务时,他们将随请求一起发送密钥散列,web服务将在其末尾比较散列密钥,如果匹配,则允许调用操作 如果我理解正确,那么我有
密钥
,当客户端请求web api服务时,他们将随请求一起发送密钥散列,web服务将在其末尾比较散列密钥
,如果匹配,则允许调用操作
如果我理解正确,那么我有一些问题。假设我向web api发送密钥散列,那么web api如何知道客户端拥有什么密钥?因为若web api必须生成客户端用于在服务端进行比较的密钥散列,那个么web api必须知道哪个客户端正在发送数据。假设web api为客户机提供不同的密钥。所以,当客户端将生成该密钥的散列并将其发送到web api时,web api如何在其末尾验证该散列
web api的HMAC身份验证的重播攻击发生了变化
为了防止web api的HMAC身份验证发生重放攻击,本文提出了一些我不清楚的观点
要点是
想象一下,一个恶意的第三方截获了一个来自合法客户端的有效(正确认证的)HTTP请求
(例如使用嗅探器)。这样的消息可以随时存储并重新发送到我们的服务器,使攻击者能够重复操作
以前由经过身份验证的用户执行。请注意,由于攻击者没有创建新消息,因此仍然无法创建新消息
知道这个秘密,也没有办法从截获的数据中检索它
1) 具有不同日期头值的请求将具有不同的签名,因此攻击者将无法修改时间戳
我们将根据密钥生成哈希,然后日期是如何到达场景的?这一点我不清楚
2) 我们引入了一个要求,即http请求的时间不得超过X[例如5]分钟-如果出于任何原因,消息延迟超过X分钟,则必须使用刷新的时间戳重新发送消息
第二点不清楚。此区域试图表示的延迟时间超过此时间,必须使用刷新的时间戳重新发送。当客户端发送第一个请求时,客户端可能会在10/15分钟后发送第二个请求
请帮助我了解如何在使用HMAC hasing防止重播攻击时保护web api。谢谢您的哈希算法对象是使用密钥构造的。然后,您可以使用该算法从字符串数据创建一个散列,其中可以包括日期时间字符串、json或xml或其他内容。必须首先将共享密钥转换为字节数组。这里有一个例子
public string Hash(string data)
{
var dataAsBytes = Encoding.UTF8.GetBytes(data);
using (var hasher = new HMACSHA256(dataAsBytes))
{
return Convert.ToBase64String(hasher.ComputeHash(dataAsBytes));
}
}
现在,假设您正在从一个c#客户机发送数据,其中包括发送数据的日期,可能还有一个guid。将数据序列化为字符串,并从该数据创建哈希。如果试图重播数据,则日期时间将完全不同。您可以在服务器上设置日期-时间差异的容差,并拒绝超过某个时间段(例如5分钟)的邮件,因此重播尝试将要求更改日期,但更改此日期将更改哈希。只有原始发件人才能为新的日期时间重新生成哈希。哈希算法对象是使用密钥构造的。然后,您可以使用该算法从字符串数据创建一个散列,其中可以包括日期时间字符串、json或xml或其他内容。必须首先将共享密钥转换为字节数组。这里有一个例子
public string Hash(string data)
{
var dataAsBytes = Encoding.UTF8.GetBytes(data);
using (var hasher = new HMACSHA256(dataAsBytes))
{
return Convert.ToBase64String(hasher.ComputeHash(dataAsBytes));
}
}
现在,假设您正在从一个c#客户机发送数据,其中包括发送数据的日期,可能还有一个guid。将数据序列化为字符串,并从该数据创建哈希。如果试图重播数据,则日期时间将完全不同。您可以在服务器上设置日期-时间差异的容差,并拒绝超过某个时间段(例如5分钟)的邮件,因此重播尝试将要求更改日期,但更改此日期将更改哈希。只有原始发件人才能为新的日期时间重新生成哈希。使用时间戳(就像发送的数据字符串的一部分)可以防止应答攻击。所以你的客户做了这样的事情:
string TimeStamp=DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff");
string HashedSignature= Hash(BillId.ToString()+UserId.ToString()+ TimeStamp + SecretCode);
RestClient.Post(BillId, UserId, TimeStamp, HashedSignature);
然后,您的服务器在尝试重新组合HashedSignature之前,检查时间戳以及它是否超过最大值(例如5秒),并拒绝它。如果它在有效的时间范围内,请尝试使用接收到的值及其对SecretCode或Key(未发送)的了解来重建它自己的ServerHashedSignature。如果收到的签名等于服务器生成的签名,则可以推断消息有效 通过使用发送的数据字符串的一部分时间戳来防止应答攻击。所以你的客户做了这样的事情:
string TimeStamp=DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss.fff");
string HashedSignature= Hash(BillId.ToString()+UserId.ToString()+ TimeStamp + SecretCode);
RestClient.Post(BillId, UserId, TimeStamp, HashedSignature);
然后,您的服务器在尝试重新组合HashedSignature之前,检查时间戳以及它是否超过最大值(例如5秒),并拒绝它。如果它在有效的时间范围内,请尝试使用接收到的值及其对SecretCode或Key(未发送)的了解来重建它自己的ServerHashedSignature。如果收到的签名等于服务器生成的签名,则可以推断消息有效 文章中写道:“密钥(如密码散列)仅在客户端和服务器之间共享一次(如在用户注册期间)”。HMAC没有共享密钥,它对消息进行散列处理