我正在使用asp.net mvc 2.0,我想知道将信息放入cookie有多安全?
就像我在我的cookie中添加了一个加密的表单身份验证票证,这样我可以将那些可能敏感的信息放在那里吗?
string encryptedTicket = FormsAuthentication.Encrypt(authTicket)
HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
就像我没有存储密码或类似的东西,但我想存储UserId,因为目前每次用户向我的网站发出请求时,我都要进行查询并获取用户Userid,因为我的每个表都是db要求您使用userId来获取正确的行。
所以这些开始快速加起来所以我宁愿说如果一个用户被认证一次那就是它,直到他们需要再次重新认证。如果我将存储此userId,我可以将如此多的请求保存到数据库。
然而,我不希望它以明文形式出现,因为潜在的人可能会使用它来尝试从数据库中获取一行,而不是真的。
显示身份验证使用的加密有多好?
答案 0 :(得分:11)
加密足够好,这不是薄弱环节。
弱链接是可以拦截cookie值,而其他人可以冒充用户。
因此,cookie中的信息足够安全,但您无法保护cookie本身。
答案 1 :(得分:10)
你问题的标题与你提出的问题并不完全一致。你在这里问两件事。
答案是肯定的。要在cookie中安全地存储数据,您必须加密要存储的数据,然后对加密数据进行签名。加密它可以防止攻击者能够读取数据,对其进行签名可以防止攻击者修改数据。这将确保数据的完整性。您可以使用此方法存储有关您要保密的用户的数据(他们的电子邮件地址,出生日期等)。 注意:在cookie中安全地存储数据不是对用户进行身份验证的安全方法!如果您将用户的用户ID存储在已签名和加密的cookie中,则不会阻止攻击者窃取整个cookie并将其发送回服务器。无法知道身份验证cookie是否来自用户输入其用户名和密码的同一浏览器。这引出了我们第二个问题(你实际问的那个)......
是。要安全地验证用户,您必须将问题1中的技术与SSL(https)结合起来。 SSL确保只有浏览器才能访问身份验证cookie(带有用户ID的签名加密cookie)。这意味着您的登录过程(接受用户名和密码,以及设置身份验证cookie)必须通过SSL进行。在服务器上设置身份验证cookie时,还必须将HttpCookie.Secure属性设置为true。这告诉浏览器在通过SSL向您的网站发出请求时仅包含此cookie。您还应该在加密的身份验证cookie中包含过期时间,以防止有人在图书馆时忘记退出您的网站。此方法的一个副作用是,只有您网站上的SSL页面才能验证用户身份。这提出了第三个问题......
你没有。但你确实有选择权。一种策略是在登录时创建两个auth cookie,一个是常规cookie,另一个是ssl-only(加密和签名)。代表用户执行敏感操作时,要求页面为SSL并使用仅SSL cookie。在进行非敏感操作(例如浏览基于其帐户所在国家/地区定制的商店)时,您可以使用常规身份验证Cookie。另一个选择是拆分页面,以便通过AJAX或json检索需要知道用户是谁的信息异步。例如:您通过http返回整个博客页面,然后您发出SSL AJAX请求以获取当前用户名,电子邮件,个人资料图片等。我们在我工作的网站上使用这两种技术。
我知道这个问题差不多一年前被问过。我是为了后人而写的。 : - )
答案 2 :(得分:6)
正如您所说,将任何数据存储在Cookie中的一个好方法是加密数据。在放入cookie之前加密,并在读取之后解密。
在存储用户标识符的示例中,选择不太可能针对您的系统使用的内容。对于用户标识,使用guid而不是可能的递增整数,这是数据库表上的PK。在攻击您的系统期间,guid不会轻易更改为成功猜测其他用户。
一旦识别或验证了用户,请继续将用户对象或关键属性存储在Session
中。
答案 3 :(得分:6)
除了cookie加密,您还应该实现旋转令牌以防止重放攻击。
这个想法是加密的cookie包含一些值,可以与服务器上的已知值进行比较。如果数据匹配,则请求成功。如果数据不匹配,那么您正在经历重播攻击并需要终止会话。
<强>更新强>
其中一条评论询问我是否打算将值存储在cookie中。答案是肯定的。整个cookie应该加密,可以通过使用HttpModule自动完成。在加密的 cookie中,您可以使用任何正常信息+更改令牌。
在每个帖子上,检查令牌。如果它有效,则允许事务,创建新的随机令牌,存储在cookie中,然后将其发送回浏览器。再次,以加密形式。
结果是你的cookie是安全的(你 使用3DES?)并且任何攻击者都有极其有限的机会窗口甚至尝试重放攻击。如果令牌没有通过集合,你可以简单地发出警报并采取适当的措施。
所有需要的服务器端都是跟踪用户及其当前令牌。这通常是一个小得多的数据库命中,而不是在每个页面加载时查找诸如用户名之类的小事。
更新2
我一直试图弄清楚这是否比保持会话中存储的更改值更好或更差。我得出的结论是,在Web服务器上存储会话中的旋转值对于防止重放攻击绝对没有任何作用,因此不如将该值放入cookie中那么安全。
考虑这种情况。浏览器发出请求。服务器查看会话ID并提取会话对象,然后执行工作,并将响应发送回浏览器。与此同时,BlackHat Bob记录了这笔交易。
然后,Bob将完全相同的请求(包括会话ID)发送到服务器。此时,服务器绝对无法知道这是来自攻击者的请求。您不能使用IP,因为代理使用可能会更改IP,您无法使用浏览器指纹识别,因为所有这些信息都会记录在初始交换中。此外,鉴于会话通常至少有30分钟且有时甚至更长,攻击者可以使用相当大的窗口来工作。因此,无论如何,为了防止重放,您必须在每次请求后向浏览器发送更改令牌。
现在,这给我们留下了一个问题,即是否还存储值,例如加密cookie中的用户ID或将其存储在会话变量中。对于会话,您会担心诸如更高的内存和CPU利用率以及负载平衡等潜在问题。对于Cookie,您有一些小于4kb的数据,并且在1kb或更小的范围内正确完成对每个请求。我想这将归结为你是否愿意添加更多/更大的服务器和内部网络设备来处理请求(会话)或支付更大的互联网管道(cookie)。
答案 4 :(得分:4)
在具有理想密码的理想世界中,这不是问题。不幸的是,在现实世界中没有什么是理想的,并且永远不会有理想的密码。安全就是解决这些现实世界的威胁。密码系统总是容易受到攻击,它可能是一种微不足道的(暴力)攻击,也可能是它自身原始的一个缺陷。更进一步,你很可能会破坏原语的实现,常见错误包括非随机或空IV,密钥管理和不正确的分组密码模式。
简而言之,这是对密码术的严重误用。最好通过使用会话变量避免这一问题来解决这个问题。这就是会话存在的原因,重点是将浏览器链接到存储在服务器上的状态数据。
编辑:加密Cookie导致ASP.NET oracle padding attack。应该通过使用Cryptographic Nonce一起避免这种情况。就像我说的,这是对密码学的严重滥用。
答案 5 :(得分:3)
对于您的特定情况(用户ID),简短的回答是否!
对于长篇答案,想象一下这个假设情景:
仍然在这种情况下,假设服务器存储了您的IP地址,但您在公司LAN上,而您的外部IP与另外100台计算机相同。想象一下,有权访问其中一台机器的人复制了你的cookie。你已经知道了,对吗? : - )
我的建议是:将敏感信息放在HTTP会话上。
更新:让会话暗示一个cookie(或至少是一个丑陋的URL),从而引导我们回到同样的问题:它可以被捕获。避免这种情况的唯一方法是添加端到端加密:HTTP + SSL = HTTPS 。 如果有人说“哦,但饼干/会话应该足以阻止大多数人”,请查看Firesheep。
答案 6 :(得分:2)
从安全的角度来看,它是好的(不是很好,但不是错误的)。然而,从性能的角度来看,这是你想要避免的事情。
所有Cookie都会在每次请求时从客户端传输到服务器。如今大多数用户可能拥有快速宽带连接,但这些连接 asymetric - 用于传输cookie数据的上游带宽通常仍然非常有限。如果您在Cookie中放入了太多信息,即使您的网络服务器具有备用容量,您的网站也会显得迟钝。它还可以提高您的带宽费用。这些是您的测试中不会显示的点,这些点很可能发生在您的公司网络中,从客户端到服务器的上游带宽很多。
更好(通用)的方法是在cookie中保留一个单独的标记,用作数据库查找信息的关键字。数据库调用也相对较慢(与已经在内存中或请求中的信息相比),但是这样的主键查找并不糟糕,而且在将数据发送到世界各地的四分之一的情况下仍然更好。请求。这对于安全性来说也更好,因为它可以尽可能地将数据保留在用户的机器上并远离线路。此标记不应该类似于您的问题中的用户标识,而是更短暂的标记 - 用于索引和隐藏更大的数据块的密钥,其中您的用户标识可能是其中的一部分。
对于您的userID,可能只有一个整数,以及其他 small 和重要数据,请将其保存在Web服务器的内存中。把它放在会话中。
答案 7 :(得分:1)
您正在查看的用途是能够在Forms Auth Ticket中存储信息的确切目的。
答案 8 :(得分:1)
没有。已经与Padding oracle attack一起显示,由于错误泄漏,接收加密数据(CBC)可能是危险的。
我绝对不是加密专家,但我最近看到了一个使用此攻击解密加密视图状态的演示。
答案 9 :(得分:1)
加密cookie中的userid值只会阻止用户知道该值是什么。它没有
加密cookie还会引入密钥管理问题。例如,当您旋转加密密钥时,您必须确保使用旧密钥的“实时”会话不会立即失败。您考虑过管理加密密钥,对吗?管理员离开后会发生什么?它受到了损害?等
您的架构(负载均衡器,服务器分发......)是否排除使用服务器端会话对象来跟踪此信息?如果没有,将userid绑定到会话对象并在服务器上保留“敏感”数据 - 用户只需要一个会话cookie。
对于您所陈述的问题,会话对象可能会更轻松,更安全。
答案 10 :(得分:0)
为了确保正确的身份验证cookie保护,您应该确保通过设置 machineKey validation =“SHA1”属性来指定安全加密/散列方案(通常在web.config中)(I使用SHA1,但如果需要,可以用不同的提供者替换它。然后,确保您的表单身份验证设置了 protection =“All”属性,以便对Cookie进行哈希和加密。不可否认性和数据安全性,一体化:)
ASP.NET将为您处理加密/解密[编辑:仅限auth cookie!] Cookie,但对于自定义Cookie,您可以使用FormsAuthentication.Encrypt(...)方法,所以请确保您没有通过查询字符串之类的其他明文方式发送UserId。
答案 11 :(得分:0)
HttpCookie c;
c.Secure = true;
显然这仅在通过SSL传输时有效,但此设置告诉浏览器除非连接是SSL,否则不发送cookie,从而防止通过中间人攻击进行拦截。如果您没有使用安全连接,那么被动嗅探连接的任何人都可以完全看到cookie中的数据。考虑到公共wifi的普及,顺便提一下,这并不像你想象的那么小。
答案 12 :(得分:0)
要解决的第一件事是所涉及的连接是否安全。如果不是,则假设您和客户之间的cookie或任何其他内容将被截获。
一旦cookie在客户机上,它就是一种责任。审查cookie盗窃,跨站点请求伪造,混淆代理问题。
答案 13 :(得分:0)