RandomNumberGenerator与RNGCryptoServiceProvider

根据RandomNumberGenerator的 MSDN文档:

应用程序代码不直接使用此类。 此抽象类作为所有加密随机数生成器的基类提供。

对于加密随机数生成器的实现,请使用派生类RNGCryptoServiceProvider。

但是,我在不同代码库中的几个场景中看到了以下代码:

byte[] bytes = new byte[...]; RandomNumberGenerator rng = RandomNumberGenerator.Create(); rng.GetBytes(bytes); 

最值得注意的是StackExchange (我假设包含SO)以及BCrypt.Net 。

因此,我有点困惑 – 上面代码返回的是什么类型的RandomNumberGenerator ? 一些代码库使用RNGCryptoServiceProvider而不是RNGCryptoServiceProvider也是一个缺陷吗?

我假设RandomNumberGenerator.Create()正在我的工作中完成,我在这里完全没有,但从技术上讲(因为它是一个抽象类)上面的代码不应该抛出错误吗?

RandomNumberGenerator.Create()方法调用RandomNumberGenerator.Create("System.Security.Cryptography.RandomNumberGenerator") ,它最终将创建RNGCryptoServiceProvider的实例。

(它在一对字典中进行一些查找,因此您可以通过在某处注册默认随机生成器来更改该调用的方法。)

返回的实际类型在编译时是未知的,只知道它将inheritanceRandomNumberGenerator类,因此您可以使用RandomNumberGenerator引用变量。

这种根据输入创建不同类型实例的方式在框架中的几个位置使用,例如通过WebRequest.Create方法。


Micrsoft的某个人已经“修复”了Create()方法的当前文档(框架4.5)。 它现在说:

“在派生类中重写时,创建可用于生成随机数据的加密随机数生成器的默认实现的实例。”

框架4.0的文档说:

“创建可用于生成随机数据的加密随机数生成器的默认实现的实例。”

这是该方法的正确描述。 我将提出一个请求,将该描述放回到较新的文档中。

RandomNumberGenerator的文档基本上搞砸了。 另一个例子,有这样的文档:

在派生类中重写时,创建加密随机数生成器的指定实现的实例。

…用于静态方法。 静态方法无法覆盖。 谁清楚地写了这些文件并没有直接思考。

我怀疑最初的意图是这样的:

应用程序代码不直接实例化此类。 此抽象类作为所有加密随机数生成器的基类提供。

我认为你发布的代码(使用静态Create方法)是完全合理的。 它与用于XmlReader.Create等的模式相同 – 静态方法选择最合适的实现。

RandomNumberGenerator.Create是一个静态工厂方法。 当然它会返回派生类的实例。 那一个不是抽象的所以这一切都是合法的。

抽象类可以任何地方使用,而不是使用更具体的类。 它们是一个版本友好的界面。