【问题标题】:How HMAC works for ASP.Net web apiHMAC 如何为 ASP.Net web api 工作
【发布时间】:2017-04-13 09:31:48
【问题描述】:

刚刚从这个 url http://www.piotrwalat.net/hmac-authentication-in-asp-net-web-api/ 阅读了一篇关于使用 HMAC 身份验证的 Web API 的文章

HMAC 完全是身份验证类型还是只是散列技术? 如果是身份验证类型,请简要告诉我为什么应该将其视为身份验证类型?

如果可能的话,有人简要讨论一下HMAC 身份验证 是什么以及这种身份验证如何用于 web api?

我从他们的文章中了解到,服务器和客户端将共享一个共同的 secret key,当客户端请求 Web api 服务时,他们将发送密钥散列以及请求,Web 服务将比较散列 secret key它的结束,如果匹配,那么它允许调用动作?

如果我理解正确,那么我有一些问题。假设如果正在向 web api 发送密钥的哈希,那么 web api 如何知道客户端有什么密钥?因为如果 web api 必须生成密钥的哈希值,客户端用于在服务端进行比较,那么 web api 必须知道哪个客户端正在发送数据。假设 web api 向他们的客户端提供不同的密钥。那么当客户端生成该密钥的哈希并将其发送到 web api 时,web api 如何在其末尾验证该哈希?

Web api 的 HMAC 身份验证的重放攻击发生变化

文章提出了一些我不清楚的点,以防止 Web api 的 HMAC 身份验证的重放攻击的机会。

点是

假设恶意第三方拦截了来自合法客户端的有效(经过适当身份验证的)HTTP 请求 (例如,使用嗅探器)。这样的消息可以随时存储并重新发送到我们的服务器,使攻击者能够重复操作 之前由经过身份验证的用户执行。请注意,仍然无法创建新消息,因为攻击者没有 知道秘密,也没有办法从截获的数据中检索它。

1) 不同 Date 头值的请求会有不同的签名,因此攻击者将无法修改时间戳

我们将根据密钥生成哈希,那么日期是如何出现的?这一点我不清楚。

2) 我们引入了一个要求,即任何 http 请求都不能早于 X [例如。 5] 分钟 - 如果由于任何原因消息延迟超过该时间,则必须使用刷新的时间戳重新发送。

第二点不清楚。这个区域试图表示的延迟超过了它必须用刷新的时间戳重新发送。客户端何时发送第一个请求,然后客户端可能会在 10/15 分钟后发送第二个请求。

请帮助我了解在使用 HMAC hasing 抵御重放攻击时如何保护 web api。谢谢

【问题讨论】:

  • 来自文章:“密钥(例如密码哈希)仅在客户端和服务器之间共享一次(例如在用户注册期间)”。 HMAC 没有 shared secret,它对 message 进行哈希处理。

标签: c# security authentication asp.net-web-api


【解决方案1】:

您的哈希算法对象是使用密钥构造的。然后,您可以使用该算法从字符串数据创建哈希,其中可以包括日期时间字符串或 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 分钟)的消息,因此重播尝试将需要更改日期,但更改此日期会更改哈希值。只有原始发件人可以为新的日期时间重新生成哈希。

【讨论】:

  • 首先告诉我 HMAC 是从特定数据创建哈希的算法,还是任何类型的身份验证。如果你通过 hmac auth 搜索 google,那么你一定会看到人们称它为 HMAC auth ......对吗?
  • 假设我正在发送从密钥创建的哈希并将其发送到 Web api 服务。所以攻击者捕获请求并提取哈希并将带有哈希的请求发送到 web api 只是为了在 web api 之前假装合法客户端。那么数据是如何进入现场的呢?
  • 数据是您从中创建哈希的内容。当服务器接收到数据和散列时,它使用数据和共享密钥重新创建散列并比较它们。如果数据发生变化或被篡改,则哈希值无效。
  • 其实维基百科的文章en.wikipedia.org/wiki/Hash-based_message_authentication_code描述的很好。我刚刚给出了实现它的代码。
  • 我想知道我们需要在服务级别编写哪些代码,因为无法进行回复攻击?
【解决方案2】:

使用发送的数据字符串的一部分,时间戳来防止回复攻击。所以你的客户做了这样的事情:

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 签名等于服务器构建的签名,那么您可以推断该消息是有效的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-10
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 2018-04-29
    • 2016-02-02
    • 1970-01-01
    相关资源
    最近更新 更多