我的最终目标是创建一个唯一且无法猜测/预测的 URL。此 URL 的目的是允许用户执行验证其电子邮件地址和重置密码等操作。这些 URL 将在设定的时间(当前设置为 24 小时)内过期。
我最初是Guid
为此目的使用 a 的,但我现在理解这介于“还好”和“非常不安全”之间,具体取决于您听哪位专家。所以,我想我会稍微加强一下我的代码,以防万一。起初我以为我会坚持使用 a 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)
instead of时究竟会发生什么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;
}
}
如果您对此有任何问题,请发表评论。