【发布时间】:2012-08-27 18:42:01
【问题描述】:
我的最终目标是创建一个独一无二且无法猜测/预测的 URL。此 URL 的目的是允许用户执行验证其电子邮件地址和重置密码等操作。这些 URL 将在设定的时间内(当前设置为 24 小时)过期。
我最初为此目的使用了Guid,但我现在理解这介于“很好”和“非常不安全”之间,具体取决于您听哪位专家。所以,我想我会稍微加强一下我的代码,以防万一。起初我以为我会坚持使用Guid,但从随机字节而不是Guid.NewGuid() 工厂方法生成它。这是我想出的方法:
public static Guid GetRandomGuid()
{
var bytes = new byte[16];
var generator = new RNGCryptoServiceProvider();
generator.GetBytes(bytes);
return new Guid(bytes);
}
我不太清楚当您使用new Guid(bytes) 而不是Guid.NewGuid() 时究竟会发生什么,但我认为这个方法所做的只是生成一个随机字节数组并将其存储 Guid 数据结构。换句话说,它不再保证是唯一的,它只保证是随机的。
由于我的 URL 需要是唯一的 和 随机的,这似乎不是一个可靠的解决方案。我现在在想,我的 URL 应该基于唯一 ID(可能是 Guid 或者,如果有的话,数据库自动递增 ID)和从 RNGCryptoServiceProvider 生成的随机序列的组合。
问题
生成一个既保证唯一又极难/不可能预测/猜测的验证/密码重置 URL 的最佳方法是什么?
我是否应该通过连接一个唯一字符串和一个随机字符串来简单地构造我的 URL?
.NET Framework 是否有内置方法可以轻松生成唯一的和可用于 URL 的随机(不可预测)序列?
如果没有,有没有好的开源解决方案?
更新
如果有人有类似的要求,我目前正在使用以下方法:
public static string GenerateUniqueRandomToken(int uniqueId)
// generates a unique, random, and alphanumeric token
{
const string availableChars =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
using (var generator = new RNGCryptoServiceProvider())
{
var bytes = new byte[16];
generator.GetBytes(bytes);
var chars = bytes
.Select(b => availableChars[b % availableChars.Length]);
var token = new string(chars.ToArray());
return uniqueId + token;
}
}
如果您对此有任何问题,请发表评论。
【问题讨论】:
-
this回答对你有帮助吗?
-
我怀疑这将是您最好的选择。它显然不符合 GUID 标准。
-
看起来您只是创建了一个 16 字节的随机数,而不是 GUID。
-
@Gabe,是的,请看我的编辑。
-
似乎只需生成一个 guid,然后使用该 guid 的哈希值即可满足您的需求(唯一性和随机性)
标签: c# security authentication cryptography guid