刚刚从此网址http://www.piotrwalat.net/hmac-authentication-in-asp-net-web-api/
阅读了有关HMAC身份验证的网络API文章HMAC 是所有身份验证类型还是只有哈希技术? 如果它是身份验证类型,那么请简要说明为什么应该将其视为身份验证类型?
如果可能,有人会简要讨论什么是 HMAC身份验证以及此类身份验证如何适用于网络API?
我从他们的文章中了解到服务器&客户端将共享一个公共secret key
,当客户端将请求web api服务时,他们将发送密钥的哈希以及请求,并且Web服务将比较其末尾的哈希值secret key
,如果匹配则允许叫行动?
如果我理解正确,那么我有一些问题。假设如果要向web api发送密钥的哈希,那么web api如何知道密钥客户端有什么?因为如果web api必须生成客户端用于在服务端进行比较的密钥的散列,那么web api必须知道哪个客户端正在发送数据。假设web api为其客户提供不同的密钥。所以当客户端生成该密钥的哈希值并将其发送到web api时,web api如何在其末尾验证该哈希值?
对于网络API
,HMAC身份验证的重播攻击发生了变化这篇文章提出了一些我不清楚的观点,以防止对web api进行HMAC身份验证的重播攻击。
要点
想象一下,恶意第三方拦截来自合法客户端的有效(经过适当身份验证的)HTTP请求 (例如,使用嗅探器)。这样的消息可以随时存储并重新发送到我们的服务器,使攻击者能够重复操作 以前由经过身份验证的用户执请注意,仍然无法创建新邮件,因为攻击者没有 知道秘密,也没有办法从截获的数据中检索它。
1)具有不同Date标头值的请求将具有不同的签名,因此攻击者将无法修改时间戳
我们将基于密钥生成哈希,然后日期如何到达场景?这一点对我来说并不清楚。
2)我们引入了一个要求,即http请求不能超过X [例如。 5分钟 - 如果由于任何原因消息延迟超过该消息,则必须重新刷新时间戳。
第二点不清楚。这个区域的意思是延迟超过它需要重新刷新的时间戳。当客户端发送第一个请求,然后客户端可以在10/15分钟后发送第二个请求。请帮助我了解如何在使用HMAC针对Replay攻击时保护web api。感谢
答案 0 :(得分:2)
您的哈希算法对象是使用密钥构造的。然后,您可以使用该算法从字符串数据创建哈希值,该字符串数据可以包含日期时间字符串或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分钟)的消息,因此重播尝试需要更改日期,但更改此日期将更改散列。只有原始发件人才能为新的日期时间重新生成哈希值。
答案 1 :(得分:1)
使用发送的数据字符串的一部分(时间戳)阻止回复攻击。所以你的客户做了这样的事情:
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之前,检查TimeStamp以及它是否早于最大值(例如5秒),并拒绝它。如果它在有效的时间范围内,尝试使用接收到的值及其对SecretCode或Key(未发送)的知识重建其自己的ServerHashedSignature。如果Received签名等于服务器构建的签名,则可以推断消息有效。
答案 2 :(得分:0)
HMAC代表基于哈希的消息身份验证代码。从HMAC的完整形式来看,我们需要了解两件事,一是消息身份验证代码,另一是基于哈希的。因此,HMAC是一种用于通过使用哈希函数来创建消息身份验证代码的机制。
我们需要记住的最重要的事情是,在使用哈希函数生成消息身份验证代码时,我们需要使用共享密钥。此外,共享秘密密钥必须在涉及发送和接收数据的客户端和服务器之间共享。
Web API中的HMAC身份验证使用哪些密钥? 首先,服务器需要生成两个密钥,一个是Public Shared APP ID,另一个是Private Secret API Key。一旦生成了密钥,服务器便有责任使用诸如电子邮件之类的安全通道将这些密钥提供给客户端,并且仅应执行一次,当客户端向服务器注册时也是如此。
一旦客户端获得了密钥,客户端便有责任生成唯一的HMAC签名(您也可以说是哈希),该签名不仅包含请求数据,还包含请求方所需的所有必要信息。服务器处理请求,然后客户端将其发送到服务器。
注意: 通常,我们需要通过组合请求数据来创建HMAC签名(哈希)。请求数据包含使用私有秘密API密钥(此密钥将不会在请求中发送)的公共APP ID,请求URI,请求内容,HTTP方法类型,时间戳和随机数。
一旦服务器接收到请求,它就会尝试使用从客户端请求接收到的数据来生成哈希(唯一的HMAC签名)。在服务器生成哈希时,它需要使用最初在客户端和服务器之间共享的同一私有密钥API密钥(客户端使用)。
一旦服务器生成了哈希(唯一的HMAC签名),那么它将与从客户端接收到的哈希进行比较。如果两个哈希值都匹配,则服务器会将此请求视为有效请求,然后继续执行,否则它只会返回未经授权的内容。
HAPI在Web API中的使用 Web API中HMAC身份验证的主要用途如下。
数据完整性:这意味着客户端发送到服务器的数据未被篡改。 请求发起:请求从受信任的客户端发送到服务器。 不是重播请求:入侵者未捕获到该请求并对其进行了重播。 如果目前尚不清楚,请放心,过一段时间后我们将通过实时示例讨论上述所有要点。
HMAC身份验证流程: 到目前为止,我们已经从客户端和服务器的角度讨论了Web API中HMAC身份验证的基础。现在,我们详细讨论客户端和服务器的流程。
正如我们已经讨论的那样,首先,服务器应创建两个密钥(公共共享APP ID和私有密钥API密钥)并将其提供给客户端。客户有责任不与任何人共享私有API密钥,此外,客户机需要安全地将私有API密钥存储在数据库或配置文件中。
首先让我们讨论HMAC身份验证中客户端的流程。
客户端流: 首先,客户端需要创建一个字符串,其中将包含客户端希望发送到服务器的所有请求数据。通常,字符串包含以下参数
HTTP方法 APP ID 随机数 请求URI 请求时间戳 请求有效载荷(请求主体)的基数64字符串表示形式 注意: 在这里,我们需要使用UNIX时间(自1970年1月1日以来的秒数)来计算“请求时间戳”值。我们需要这样做,以克服客户端和服务器之间出现不同时区问题的可能性。
Nonce是一个随机数或字符串,每个请求仅使用一次。在这里,我们将使用GUID创建Nonce。
一旦通过组合所有参数生成了字符串,则客户端有责任通过使用任何哈希算法(例如SHA256)来生成上述字符串的HASH(唯一签名)。这里需要记住的重要一点是,在生成唯一签名(哈希)的同时,您需要使用服务器最初提供的私有秘密API密钥。
一旦客户端生成了唯一签名(哈希),则客户端需要使用自定义方案(例如“ hmacauth”)在请求标头中发送该签名(哈希)。
在这里您可以使用任何标头,但是为了简化演示,我们将使用Authorization标头,但并非强制性的,您可以使用任何标头。
标头中的数据将包含公共共享的APP ID,请求时间戳和以冒号“:”分隔的随机数。由于我们将使用Authorization标头,因此Authorization标头的格式应如下所示:
[授权:hmacauth APPId:签名:Nonce:时间戳记
服务器端的流程: 步骤1: 服务器接收包含请求数据和授权标头的请求。 Authorization标头包含HAMC签名。服务器需要从Authorization标头中提取诸如APP Id,Signature,Nonce和Request Timestamp之类的值。
第2步: 一旦服务器从Authorization标头中提取了值,然后使用APP ID(我们将在步骤1中获得的值),服务器将尝试获取Private Secret API密钥,该密钥通常存储在某些安全存储库中,例如数据库或在配置文件中。
Step3: 服务器获得私有秘密API密钥后,便尝试通过将接收到的请求内容数据与提取的数据(例如在步骤1中提取的APP Id,Nonce和Request Timestamp)组合在一起来重建字符串。这里需要了解的重要一点是,参数顺序和编码格式应与客户端遵循的顺序相同。
Step4: 一旦构建了字符串,服务器便有责任通过使用客户端使用的相同哈希算法(即SHA256)使用服务器已经在Step2中检索到的私有秘密API密钥来生成哈希值。
Step5: 在服务器上生成哈希后,服务器会将生成的哈希与客户端发送的哈希进行比较,如果两个哈希均匹配,则服务器会将此请求视为有效请求并处理该请求,否则它仅返回401未经授权。
如果您想了解如何在实践中实现它,请阅读以下文章。
https://dotnettutorials.net/lesson/hmac-authentication-web-api/