我一直在尝试用 C# 编写一个简单的辅助方法,该方法生成具有任何给定长度和字符集的加密安全随机字符串。我知道如果您想要加密安全,您不应该使用
Random
类。在过去,总是建议使用 RNGCryptoServiceProvider
类作为 Random
的替代品,以提供加密安全性。该类现在已过时,应该使用 RandomNumberGenerator
来代替。
现在,我感到困惑的是,这个著名的问题中的许多答案都使用新的
RandomNumberGenerator
类——例如这个——正在使用GetBytes()
方法,然后做很多其他的事情之后的事情让事情顺利进行;但我不明白为什么他们不使用 GetInt32()
来代替,然后使用结果作为字符集中的索引?看起来这会让事情变得更简单。
这就是我要说的:
public string GenerateRandomString(int length, string charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
{
char[] result = new char[length];
for (int i = 0; i < length; i++)
result[i] = charSet[RandomNumberGenerator.GetInt32(charSet.Length)];
return new string(result);
}
我的问题是这样的:这种生成随机字符串的加密方式是否合理?我从未见过这样做的事实让我不确定,这就是我问这个问题的原因。如果不是,您能解释一下原因吗?
谢谢你。
从您链接的文档中:
加密随机数生成器创建加密的强随机值。
好的,现在我们来看看
GetInt32
:
使用加密的强随机数生成器生成 0(含)和指定的排它上限之间的随机整数。
(强调我的)
最重要的是,它后来指出:
此方法使用丢弃并重试策略来避免简单的模算术运算会产生的低值偏差。
所以它可以用来可靠地生成随机字符串,是的。
至于推理,嗯,
RNGCryptoServiceProvider
没有GetInt32
,它只有GetBytes
,所以当然以前使用RNGCryptoServiceProvider
的旧代码,然后匆忙修改为使用RandomNumberGenerator
来修复过时的警告不会使用新方法。