我想使用安全的PRNG生成盐。我已经读过,实现此目的的最新和推荐方法是为RandomNumberGenerator
创建GetBytes
实例。但是,我不太确定应该采用哪种方式:
// CODE 1
private static byte[] GenerateSaltNewInstance(int size)
{
using (var generator = RandomNumberGenerator.Create())
{
var salt = new byte[size];
generator.GetBytes(salt);
return salt;
}
}
// CODE 2
private static RandomNumberGenerator rng = RandomNumberGenerator.Create();
private static byte[] GenerateSaltStatic(int size)
{
var salt = new byte[size];
rng.GetBytes(salt);
return salt;
}
有什么区别?基本上在这个方法的第一个版本中,我每次都在创建一个RandomNumberGenerator
的新实例。在第二个中,我使用了一次初始化的静态实例。
我应该选择哪一个?在文章中我看到人们遵循第一条路径,但我不认为为什么创建RandomNumberGenerator
10000次会更好:P每次使用新实例是否更安全?
答案 0 :(得分:6)
第一种方法保证是线程安全的,第二种方法取决于Create()
方法返回的对象的线程安全性。
在.NET的当前实现中,它返回RNGCryptoServiceProvider
并且该类型可以安全地同时从多个线程调用GetBytes
,但不能保证默认Create()
将会始终在框架的未来版本中返回RNGCryptoServiceProvider
。更安全的选择是根据需要创建它或直接使用RNGCryptoServiceProvider
并保证线程安全。
安全方面,他们都应该同样安全地调用Crypto Service Provider,这样可以获得硬件支持的最随机数。