RandomNumberGenerator正确用法

Pat*_*ski 4 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;
}
Run Code Online (Sandbox Code Playgroud)

有什么不同?基本上在这个方法的第一个版本中,我RandomNumberGenerator每次都在创建一个新的实例.在第二个我使用初始化一次的静态实例.

我应该选择哪一个?在文章中,我看到人们遵循第一条路径,但我不认为为什么创建RandomNumberGenerator10000次会更好:P每次使用新实例是否更安全?

Sco*_*ain 6

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

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

安全方面,他们都应该同样安全地呼叫加密服务提供商,它将尽可能获取硬件支持的最随机数.