将数据放入cookie中是否安全?

cho*_*bo2 14 .net c# security encryption cryptography

我正在使用asp.net mvc 2.0,我想知道将信息放入cookie有多安全?

就像我在我的cookie中放入一个加密的表单身份验证票据,这样我可以将那些可能敏感的信息放在那里吗?

string encryptedTicket = FormsAuthentication.Encrypt(authTicket)
HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
Run Code Online (Sandbox Code Playgroud)

就像我没有存储密码或类似的东西,但我想存储UserId,因为目前每次用户向我的网站发出请求时,我必须进行查询并获取用户Userid,因为我的数据库中的每个表都需要你使用userId获取正确的行.

所以这些开始快速加起来所以我宁愿这样,如果用户被认证一次,那就是它,直到他们需要再次重新认证.如果我将存储此userId,我可以将如此多的请求保存到数据库中.

然而,我并不希望它以明文形式浮动,因为潜在的人可能会使用它来尝试从数据库中获取一行,而实际上它们应该不存在.

显示身份验证使用的加密有多好?

Guf*_*ffa 11

加密足够好,这不是薄弱环节.

弱链接是cookie值可能被截获,而其他人可能会冒充用户.

因此,cookie中的信息足够安全,但您无法保护cookie本身.

  • @Guffa我投票给你了,因为我不想让任何人尝试这个错误.会话是将浏览器与服务器端数据相关联,在cookie中使用密码会破坏目的. (4认同)
  • -1这个帖子后,asp.net oracle padding攻击出来了.但它完全支持我的论点.@Guffa不写安全系统,你的方法是有缺陷的. (4认同)

Rob*_*ney 10

你问题的标题与你提出的问题并不完全一致.你在这里问两件事.

1.有没有一种安全的方式将数据存储在cookie中?

答案是肯定的.要在cookie中安全地存储数据,您必须加密要存储的数据,然后对加密数据进行签名.加密它可以防止攻击者能够读取数据,对其进行签名可以防止攻击者修改数据.这将确保数据的完整性.您可以使用此方法存储有关您要保密的用户的数据(他们的电子邮件地址,出生日期等). 注意:在cookie中安全地存储数据不是验证用户身份的安全方法! 如果您将用户的用户ID存储在已签名和加密的cookie中,则不会阻止攻击者窃取整个cookie并将其发送回服务器.无法知道身份验证cookie是否来自用户输入其用户名和密码的同一浏览器.这引出了我们第二个问题(你实际问的那个)......

2.是否有一种安全的方法来使用cookie验证用户?

是.要安全地验证用户,您必须将问题1中的技术与SSL(https)结合起来.SSL确保只有浏览器才能访问身份验证cookie(带有用户ID的签名加密cookie).这意味着您的登录过程(接受用户名和密码,以及设置身份验证cookie)必须通过SSL进行.在服务器上设置身份验证cookie时,还必须将HttpCookie.Secure属性设置为true.这告诉浏览器在通过SSL向您的网站发出请求时仅包含此cookie.您还应该在加密的身份验证cookie中包含过期时间,以防止有人在图书馆时忘记退出您的网站.此方法的一个副作用是,只有您网站上的SSL页面才能验证用户身份.这提出了第三个问题......

3.如何在不使用SSL的情况下安全地对用户进行身份验证?

你没有.但你确实有选择权.一种策略是在登录时创建两个auth cookie,一个常规cookie和一个仅ssl-only(加密和签名).代表用户执行敏感操作时,要求页面为SSL并使用仅SSL cookie.在进行非敏感操作(例如浏览基于其帐户所在国家/地区定制的商店)时,您可以使用常规身份验证Cookie.另一个选择是拆分页面,以便通过AJAX或json检索需要知道用户是谁的信息异步.例如:您通过http返回博客的整个页面,然后您发出SSL AJAX请求以获取当前用户名,电子邮件,个人资料图片等.我们在我工作的网站上使用这两种技术.

我知道这个问题差不多一年前被问到了.为了后人的缘故,我正在写这篇文章.:-)


p.c*_*ell 6

如您所述,将任何数据存储在cookie中的良好做法是加密数据.在放入cookie之前加密,并在读取之后解密.

在存储用户标识符的示例中,选择不太可能针对您的系统使用的内容.对于用户标识,请使用guid而不是数据库表上PK 的可能递增整数.在攻击您的系统期间,不会轻易更改guid以成功猜出其他用户.

一旦识别或验证了用户,请继续并存储用户对象或密钥属性Session.

  • 您可能希望看到以下用于自动加密cookie的http模块:http://www.codeproject.com/KB/IP/CookieEncryptionModule.aspx?msg = 2577001#xxx2577001xx (2认同)

Not*_*tMe 6

除了cookie加密,您还应该实现旋转令牌以防止重放攻击.

这个想法是加密的cookie包含一些值,可以与服务器上的已知值进行比较.如果数据匹配,则请求成功.如果数据不匹配,那么您正在经历重播攻击并需要终止会话.

更新
其中一条评论询问我是否打算将值存储在cookie中.答案是肯定的.整个cookie应该加密,可以通过使用HttpModule自动完成.加密 cookie 内部是您的任何常规信息+更改令牌.

在每个帖子上,检查令牌.如果它有效,则允许事务,创建新的随机令牌,存储在cookie中,然后将其发送回浏览器.再次,以加密形式.

结果是你的cookie是安全的(你正在使用3DES?),任何攻击者都有极其有限的机会甚至可以尝试重放攻击.如果令牌没有通过集合,您可以简单地发出警报并采取适当的措施.

所有需要的服务器端都是跟踪用户及其当前令牌.这通常是一个小得多的数据库命中,而不是在每个页面加载时查找诸如用户名之类的小东西.

更新2
我一直试图弄清楚这是否比保持会话中存储的更改值更好或更差.我得出的结论是,在Web服务器上存储会话中的旋转值对于防止重放攻击绝对没有任何作用,因此比将该值放入cookie中更不安全.

考虑这种情况.浏览器发出请求.服务器查看会话ID并提取会话对象,然后执行工作,并将响应发送回浏览器.与此同时,BlackHat Bob记录了这笔交易.

Bob然后将完全相同的请求(包括会话ID)发送到服务器.此时,服务器绝对无法知道这是来自攻击者的请求.您不能使用IP,因为代理使用可能会更改IP,您无法使用浏览器指纹识别,因为所有这些信息都会记录在初始交换中.此外,鉴于会话通常至少有30分钟,有时甚至更长,攻击者有一个相当大的窗口可以工作.

因此,无论如何,为了防止重放,您必须在每次请求后向浏览器发送更改令牌.

现在,这给我们留下了一个问题,即是否还要将值(如用户ID)存储在加密cookie中,还是将其存储在会话变量中.对于会话,您会担心诸如更高的内存和CPU利用率以及负载平衡等潜在问题.对于Cookie,您有一些小于4kb的数据,并且在1kb或更小的范围内正确完成对每个请求.我想这将归结为你是否愿意添加更多/更大的服务器和内部网络设备来处理请求(会话)或支付稍大的互联网管道(cookie).