缓解Web服务器上的RsaCryptoServiceProvider线程安全问题

|| 我有一个
X509Certificate2
实例,并获得了
PrivateKey
属性,即
RsaCryptoServiceProvider
。 MSDN文档证明此“ 2”类不是线程安全的。因此,如果给出一些X.509证书,我需要对多个线程(通常在Web服务器上)执行非对称加密,那么创建“ 2”的多个实例的最佳方法是什么? “ 0”上的私钥没有标记为可导出,因此我不能简单地将原始“ 2”上的参数导出并重新导入到另一个实例中,以解决线程安全问题。 我是通过
X509Store
获取原始的,但是这似乎是
X509Certificate2
实例的集合,因此,如果我想要
RsaCryptoServiceProvider
的新实例,则必须实例化新的
X509Store
来找到新的
X509Certificate2
,以获得新的
RsaCryptoServiceProvider
。仅仅让.NET克隆
RsaCryptoServiceProvider
实例似乎很繁重。 有没有更好的方法?     
已邀请:
RsaCryptoServiceProvider
,尽管它的MSDN文档指出它不是线程安全的,但它似乎足以一次加密/解密多个线程的线程安全。我编写了以下应用程序来使用此类测试高并发性,并且该应用程序没有崩溃或无法正确加密/解密:
using System;
using System.Diagnostics;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Threading;

namespace ConsoleApplication1 {
    class Program {
        static bool exit;

        static void Main(string[] args) {
            var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            try {
                store.Open(OpenFlags.OpenExistingOnly);

                Func<RSACryptoServiceProvider> rsaFactory = null;
                X509Certificate2 winningCert = null;
                exit = true;
                foreach (X509Certificate2 cert in store.Certificates) {
                    try {
                        var result = store.Certificates.Find(X509FindType.FindByThumbprint, cert.Thumbprint, false).Cast<X509Certificate2>().FirstOrDefault();
                        rsaFactory = () => (RSACryptoServiceProvider)result.PrivateKey;
                        UseRsa(rsaFactory());
                        winningCert = cert;
                        break;
                    } catch (CryptographicException) {
                        Console.WriteLine(\"Cert {0} failed\", cert.Thumbprint);
                    }
                }

                exit = false;
                Console.WriteLine(\"Winning cert: {0}\", winningCert.Thumbprint);
                RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)winningCert.PrivateKey;
                rsaFactory = () => rsa;
                Thread[] threads = new Thread[16];
                for (int i = 0; i < threads.Length; i++) {
                    threads[i] = new Thread(state => UseRsa(rsaFactory()));
                    threads[i].Start();
                }

                Thread.Sleep(10000);

                exit = true;
                for (int i = 0; i < threads.Length; i++) {
                    threads[i].Join();
                }

                Console.WriteLine(\"Success.\");
            } finally {
                store.Close();
            }
        }

        static void UseRsa(RSACryptoServiceProvider rsa) {
            var rng = RandomNumberGenerator.Create();
            var buffer = new byte[64];

            do {
                rng.GetBytes(buffer);
                var cipher = rsa.Encrypt(buffer, true);

                var plaintext = rsa.Decrypt(cipher, true);
                for (int i = 0; i < buffer.Length; i++) {
                    if (buffer[i] != plaintext[i]) {
                        Debugger.Break();
                    }
                }
            } while (!exit);
        }
    }
}
    

要回复问题请先登录注册