RandomNumberGenerator正确用法

时间:2015-08-09 20:27:40

标签: c# random

我想使用安全的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每次使用新实例是否更安全?

1 个答案:

答案 0 :(得分:6)

第一种方法保证是线程安全的,第二种方法取决于Create()方法返回的对象的线程安全性。

在.NET的当前实现中,它返回RNGCryptoServiceProvider并且该类型可以安全地同时从多个线程调用GetBytes,但不能保证默认Create()将会始终在框架的未来版本中返回RNGCryptoServiceProvider。更安全的选择是根据需要创建它或直接使用RNGCryptoServiceProvider并保证线程安全。

安全方面,他们都应该同样安全地调用Crypto Service Provider,这样可以获得硬件支持的最随机数。