繁体   English   中英

快速创建BouncyCastle SecureRandom实例是否有问题?

[英]Is rapidly creating BouncyCastle SecureRandom instances problematic?

正如在随机数生成器中所指出的, 只生成一个随机数 ,每次需要另一个随机数时,创建System.Random的新实例通常是不正确的,因为System.Random是根据时钟播种的,因此在相同的刻度将产生相同的随机数。 因此,一种常见的做法(至少在单线程应用程序中)是创建一个存储在静态字段中的Random实例,用于生成所有随机数。

另一方面, RNGCryptoServiceProvider没有这个特殊的缺陷......但实例化成本显然RNGCryptoServiceProvider ,因此再次建议存储和重用它的单个实例。

Org.BouncyCastle.Security.SecureRandom怎么Org.BouncyCastle.Security.SecureRandom 我是否同样需要存储和重用它的单个实例,或者每次我需要另一个随机数时,按需创建实例基本上没问题?

我们可以再次(比如在相关问题中)查看源代码来得出一些结论( SecureRandom源代码供参考)。

构造函数中的所有工作都用于创建伪随机生成器:

private static DigestRandomGenerator CreatePrng(string digestName, bool autoSeed)
{
    IDigest digest = DigestUtilities.GetDigest(digestName);
    if (digest == null)
        return null;
    DigestRandomGenerator prng = new DigestRandomGenerator(digest);
    if (autoSeed)
    {
        prng.AddSeedMaterial(NextCounterValue());
        prng.AddSeedMaterial(GetNextBytes(Master, digest.GetDigestSize()));
    }
    return prng;
}

创建摘要(哈希)不需要任何费用(相对于其他工作)。 例如,默认情况下使用的Sha256Digest (使用空构造函数)只分配小byte[]缓冲区。 创建DigestRandomGenerator本身也不需要任何费用(耦合小缓冲区)。 主要工作在这里:

prng.AddSeedMaterial(GetNextBytes(Master, digest.GetDigestSize()));

它使用“主”RNG生成种子值。 完整.NET平台上的主RNG是RNGCryptoServiceProviderSecureRandom存储在静态字段中并仅初始化一次)。 因此,创建SecureRandom时的所有工作都是为伪RNG创建加密随机种子。

我想说,最好不要每次创建新实例,至少对于小代(对于一两个NextInt()调用),因为如果为每个生成的数字创建新实例 - 基本上是成本的两倍(一次)为种子生成加密随机数,并生成一个目标随机数)。 因为(据我所知), SecureRandom是线程安全的 - 没有太多理由不重用一个实例。

旁注 - 我不认为RNGCryptoServiceProvider很难创建链接声明。 它的构造函数如下:

public RNGCryptoServiceProvider()
  : this((CspParameters) null)
{
}

[SecuritySafeCritical]
public RNGCryptoServiceProvider(CspParameters cspParams)
{
  if (cspParams != null)
  {
    this.m_safeProvHandle = Utils.AcquireProvHandle(cspParams);
    this.m_ownsHandle = true;
  }
  else
  {
    // we are interested in this path
    this.m_safeProvHandle = Utils.StaticProvHandle;
    this.m_ownsHandle = false;
  }
}

因此,当您创建新实例(不提供csp)时 - 它会重用相同的Utils.StaticProvHandle ,因此它使用相同的“非托管”RNG提供程序实例。 这反过来意味着创建新实例并重用相同的实例在性能上没有区别。 也许在以前的.NET版本中,它不是这样,不确定。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM