我使用以下代码生成反CSRF令牌:
TokenCSRF = new Random(Guid.NewGuid().GetHashCode()).Next(1, 9999).ToString();
这个标记是否可以猜测或者是按预期真正随机的?
编辑:我用以下代码替换了令牌生成器:
byte[] byt = new byte[sizeof(Int32)];
RNGCryptoServiceProvider rngCrypto = new RNGCryptoServiceProvider();
rngCrypto.GetBytes(byt);
return BitConverter.ToInt32(byt, 0);
答案 0 :(得分:8)
这个标记是否可以猜测或者是按预期真正随机的?
这是一个错误的问题。
Mike z的评论是正确的。 Guids保证唯一,而不是随机。有不同的guid生成技术,其中一些比其他技术更随机。特别是,允许guid发生器生成顺序guid。大多数人不这样做,但如果你使用guid作为非唯一性的东西,你就是在标签之外使用它。当安全性在线时,我不喜欢在标签外做任何。
特别是,我们没有证据表明任何安全专业人员已经审查了guid生成器或哈希生成器中的代码,以确保它具有足够的熵来击败攻击者。您应该根据专家审核的工具确定您的安全性。
虽然我们在这里:代码本身很奇怪。它假定guid的散列具有足够的熵来为随机数生成器播种,然后从该RNG生成单个5位十进制数。 假设您手头已经有32位随机数;你为什么不把它当作你的随机数,如果它已经是随机性的来源,足以成为种子?你有一个随机种子,它足够大,可以成为你寻找的随机数!将它送入随机不会使它更多随机。
那就是说,你根本不应该使用它。
要问的正确问题是:
出于安全目的生成随机数的正确方法是什么?
使用加密强度随机性生成器,其标签使用正是如此。 .NET运行时库中有一个可用;用它!
进一步阅读:
https://blogs.msdn.microsoft.com/ericlippert/tag/guids/
第3部分特别与你的问题密切相关。
答案 1 :(得分:1)
GUID是可猜测的,因为它的一部分由生成它的机器识别,而部分是时间戳。没有比播种当前时间戳更好的了,这也是可以猜测的。
如果要生成安全令牌,您可能希望使用System.Security.Cryptography.RNGCryptoServiceProvider类或类似的方法。
在相关说明中,不要将令牌限制为10K值或任何小的值。你会为暴力攻击打开自己。至少使用像64位这样的东西然后你就会安全。如果您依赖加密RNG,您可能希望生成8或16个字节,然后将它们转换为使用base-64编码的字符串。这对我来说听起来很安全。