在ASP.NET(C#)中实现安全,独特的"一次性"激活URL

Tys*_*yst 23 c# t-sql asp.net security cryptography

我有一个场景,我正在构建的网站的用户需要能够在不必登录的情况下将一些基本信息输入到webform中.该站点正在使用ASP.NET/C#开发,并使用MSSQL 2005作为其关系数据.

将向用户发送来自站点的电子邮件,为他们提供唯一链接以输入他们所需的特定信息.该电子邮件非常类似于我们在注册论坛等网站时所获得的电子邮件样式,其中包含一个随机生成的,唯一的URL参数,专门用于单一目的(例如验证论坛的电子邮件地址).

我的疑问是关于此问题的安全实施.我正在考虑使用GUID作为唯一标识符,但我不确定它在安全领域的影响.

  1. GUID是否足够长,以至于不能轻易猜到值(或随着时间的推移强迫)?
  2. .NET的GUID实现是否足够随机,因为在"密钥空间"中生成所有可能值的机会相等?

  3. 如果使用GUID是一种可接受的方法,那么网站是否应该通过URL重写或通过将数据表中的信息与GUID作为参考相关联来重定向到信息?

  4. 使用URL重写会隐藏数据的真正来源吗?

  5. 我应该考虑使用TSQL的SELECT NEWID()作为.NET实现的GUID生成器吗?

  6. 我对这个问题的解决方法完全错了吗?

非常感谢,

卡尔

Avi*_*viD 14

  1. 不,GUID不是完全随机的,并且大多数位是静态的或容易猜测的.
  2. 不,它们不是随机的,参见1.实际上有非常少量的比特实际上是随机的,并且在那时加密不强.
  3. 不是,见1和2.
  4. 你可以,但不需要...最后看到我的解决方案.
  5. 不,见1和2
  6. 是.

你应该使用什么而不是GUID,是一个加密强大的随机数生成器 - 使用System.Security.Cryptography.RNGCryptoServiceProvider,生成长(比方说,32字节)数据串,然后base64编码.
此外,假设这是某种敏感数据注册,您需要限制链接的有效性,比如60分钟或24小时 - 取决于您的网站.
您需要将这些值的映射保留给特定用户.然后,您可以根据需要自动向他提供正确的表格.不需要进行url重写,只需将其用作用户的标识符(在此页面上).
当然,不要忘记这个URL应该是HTTPS ...

顺便说一句,只是一个注释 - 在电子邮件中放置某种形式的文本的好习惯,解释用户不应该点击匿名电子邮件中的链接,通常你的网站不会发送,并且他们不应该在点击blablabla后输入他们的密码... .

哦,差点忘了 - 你应该考虑的另一个问题是如果用户想要发送几封电子邮件会发生什么,例如点击几次注册.他能一遍又一遍地做到这一点,并获得许多有效的URL吗?只有最后一个有效吗?或者可能一遍又一遍地重新发送相同的值?当然,如果一个匿名用户可以提出这个电子邮件的请求,那么DoS可能会成为一个问题...更不用说如果他输入他自己的电子邮件,他也可以输入任何随机地址,淹没一些可怜的笨蛋收件箱并可能导致您的邮件服务器被列入黑名单...
没有正确的答案,但需要在您的应用程序的上下文中考虑.


Meh*_*ari 11

  1. 是的,2 128足够长.
  2. 不,GUID实现旨在生成唯一的 GUID而不是随机的GUID.您应该使用加密安全随机数生成器(例如RNGCryptoServiceProvider)生成16个随机字节并Guid使用该初始化结构.
  3. 是的,这是一种可接受的方法.两者都有效.
  4. 是的,如果你没有透露任何其他线索
  5. 没有, goto 2
  6. 不,这很好.您只需使用加密安全随机数生成器来生成GUID.

  • @AviD:我从未说过你通过调用`Guid.NewGuid`来生成GUID.我所关心的只是GUID格式.使用随机数生成器生成16个任意字节,并以GUID格式打包.是的,它可能不会作为全球唯一标识符,但无关紧要.GUID*格式*只是一种方便的格式. (3认同)

Mat*_*hen 5

我建议仅使用普通随机数,例如来自RNGCryptoServiceProvider.GetBytes的字节。GUID 并不意味着完全随机。它们具有固定位,并且某些版本使用您的 MAC 地址。GetBytes 还为您提供了使用超过 128 位的选项(尽管这应该足够了)。

我认为最好不要将用户数据放在 url 中。尽管 HTTPS 可以在传输过程中保护它,但它可能仍然存在于用户的浏览器历史记录等中。最好使用 POST 并将随机数与数据库的一行相关联。