ASP.Net MVC cookies - 防篡改?

ASP.Net MVC cookies - tamper resistant?

所以我正在阅读我在 /r/netsec 上找到的一篇简洁的文章:

https://paragonie.com/blog/2015/05/using-encryption-and-authentication-correctly

真正让我陷入困境的一件事是,可以在加密的 cookie 中稍微翻转一下,实际上会对包含的数据进行有意义的更改。

确保所有流量都通过 SSL 很容易(这不是关于安全传输的问题),但这让我真正开始思考消息完整性以及如何查看原始 cookie 是否已被篡改。通常我只会将经过身份验证的用户 ID 存储在 cookie 中,并在我的防火墙后面处理所有其他内容。如果我可以篡改该 cookie 以从客户端更改用户 ID 怎么办?上面的文章表明这​​是可能的,并提供了使用 libsodium 解决此问题的建议。我知道这个库(我自己没用过),但这让我进一步陷入困境,认为需要 ASP 内置安全机制之外的东西。

具体关于内置 ASP 安全性,我是否需要做任何尚未以处理 cookie 安全性的标准方式实现的特殊操作(让 OWIN 做它的事情或使用 FormsAuthentication.Encrypt)?如果不是,消息完整性是如何处理的?

进一步阅读使我在代码项目上找到了这个 HttpSecureCookie class: http://www.codeproject.com/Articles/13665/HttpSecureCookie-A-Way-to-Encrypt-Cookies-with-ASP

上面说的是使用机器密钥来做cookie防篡改,但是我不清楚具体是如何做到防篡改的。这将如何防止恶意用户将原始文章中指示的位翻转到加密的 cookie?

只需将 forms authentication protection 方法设置为 Encryption and validation

这将防止位翻转攻击,因为一旦位被翻转,签名将不匹配。验证意味着消息已签名。

验证是如何工作的?

验证算法can be set in web.config in the validationAlgorithm attribute of the machineKey element.

默认情况下,它使用 HMACSHA256,这是一个 SHA-256 hash applied using the HMAC 结构。

哈希对 cookie 进行签名 - 如果 cookie 值发生变化,哈希将不再匹配。由于最终用户不知道这个秘密,他们无法更改 cookie 值。

例如尝试 on here 为消息 foo 使用秘密 secret.

生成 SHA-256 HMAC

这应该给你:773ba44693c7553d6ee20f61ea5d2757a9a4f4a44d2841ae4e95b52e4cd62db4

请注意,如果您将 foo 更改为其他内容,则哈希值会有所不同。这就是防止 cookie 被篡改的方法。此 cookie 将设置如下。

Set-Cookie: id=foo&hash=773ba44693c7553d6ee20f61ea5d2757a9a4f4a44d2841ae4e95b52e4cd62db4

请注意,该值是明文的,但哈希签名可防止任何篡改。这只是验证。

使用加密和验证选项 foo 将首先加密,签名将防止任何位翻转。这使得最终用户可以私密地存储值。

如果您在 Forms 身份验证之外实现此功能,请记住在 cookie 中存储某种类型的到期日期并将其包含在签名中。这个日期可以在服务器端检查。默认情况下,表单身份验证会执行此操作。

否则,用户可能会记下有效的 cookie 值。假设他们获得了一天的管理员访问权限并发出了以下 cookie:

username=admin&hash=71b3ba92493e92ce3c60042988e9de428f44b35a6be61c8da99fa43f950d3056

当管理员权限被撤销的第二天,用户需要做的就是使用 cookie 编辑器将他们的 cookie 设置为上述值,他们将再次拥有系统的管理员权限。

要解决这个问题,您可以像这样发出一个 cookie:

username=admin&expiry=20150508100000&hash=e38a3a003b30ceb9060165d19bb8d2a2bca6c7c531a37e888448ca417166db3a

这在 cookie 中有到期日期,在哈希中签名。任何修改到期日期的尝试都将导致 HMAC 不匹配,并且用户将无法访问。这将防止任何篡改 cookie 到期日期或任何娱乐客户端。

What are our other don't-mess-with-my-cookie options if not using forms authentication?

另一种方法是存储一个完全随机的、加密安全的生成字符串并将其设置为 cookie 值。在您的服务器上,将其存储为使用 SHA-2 散列(无需加盐)并查找此值以检索有关用户会话的详细信息。当然这有更多的开销。优点是可以通过删除条目在服务器端终止会话。

这也可以通过表单身份验证来完成,但是您需要实施自定义提供程序。