static RNGCryptoServiceProvider - 它是否安全& threadafe用于生成会话和随机密码?

时间:2009-08-10 23:37:22

标签: c# .net asp.net cryptography

我正在构建一个Web服务,要求我生成自定义会话和随机密码等。

我想知道是否制作一个静态类并为整个网站使用1个静态RNGCryptoServiceProvider实例是一个好主意? 1.来自多个http请求实例的线程是否安全? 2.安全吗?如果我允许某人在很短的时间内生成许多会话,是否有可能找出RNG的状态并预测下一个会话?

在我的服务中,其他用户知道有人登录时,我最初创建了一个新的RNGCryptoServiceProvider,当他们登录生成会话时,但我担心的是,如果这是基于当前的日期时间,理论上不可能有人只需要如果他们大致知道他们登录的第二个会话,那么通过几千个会话来“猜测”另一个用户的会话?

public static class random
{
    private static RandomNumberGenerator _rng;
    protected static RandomNumberGenerator rng
    {
        get
        {
            if (_rng == null) _rng = new RNGCryptoServiceProvider();
            return _rng;
        }
    }
    public static byte[] Bytes(int number)
    {
        var value = new byte[number];
        rng.GetBytes(value);
        return value;
    }
    public static byte Byte { get { return Bytes(1)[0]; } }
    public static int Int { get { return BitConverter.ToInt32(Bytes(4), 0); } }
    public static long Long { get { return BitConverter.ToInt64(Bytes(8), 0); } }
}

3 个答案:

答案 0 :(得分:9)

CLR中基于CSP的RNG只是CryptGenRandom的包装。与所有CSP函数一样,它们围绕HCRYPTPROV上下文句柄工作。如果我没记错的话,提供者在进入“上下文”时所做的第一件事就是获得一个保护“上下文”的关键部分。因此虽然该函数最有可能在线程之间保持稳定,但您确实应该为每个线程使用单独的一个来避免争用。

<强>更新

根据这个MSDN Magazine,CLR 可能使用实例缓冲区而不是堆栈缓冲区,这使得RNGCryptoServiceProvider在未来的实现中跨线程不安全:

  

请注意,正如当前实施的那样   .NET Framework 2.0 ,.   无参数构造函数   RNGCryptoServiceProvider创建   线程安全的实例。就这样,我们   本来可以创建我们的私人会员   而是一个私人静态   会员,并且这样做不必   创建一个新的RNGCryptoServiceProvider   每个实例的实例   CryptoRandom。但是,这个   线程安全目前不是   记录,也不以任何方式烘焙   进入班级的合同或   接口。鉴于此,我们没有   我们依靠它来实施。

请注意,此用法与本机API线程安全无关,缓冲区问题是CLR包装器问题。此外,如果您使用带有byte []的RNGCryptoServiceProvider构造函数,那么肯定是不安全的

答案 1 :(得分:6)

1)如果它应该是加密安全的,那么这种猜测应该是不可行的。

2)在旁注中,我建议在静态属性annd中删除JIT实例化,而不是执行以下操作:

protected static readonly RandomNumberGenerator _rng = new RNGCryptoServiceProvider();

答案 2 :(得分:-1)

[ThreadStatic] protected static readonly RandomNumberGenerator _rng = new RNGCryptoServiceProvider();

ThreadStaticAttribute应该确保每个帖子都有自己的。