加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net – 减轻Web服务器上的RsaCryptoServiceProvider线程安全

发布时间:2020-12-16 09:45:08 所属栏目:asp.Net 来源:网络整理
导读:我有一个X509Certificate2实例,并获取其PrivateKey属性,这是一个RsaCryptoServiceProvider. MSDN文档表明此RsaCryptoServiceProvider类不是线程安全的.因此,如果给出一些X.509证书,我需要在多个线程上执行非对称加密(通常在Web服务器上),创建RsaCryptoServic
我有一个X509Certificate2实例,并获取其PrivateKey属性,这是一个RsaCryptoServiceProvider. MSDN文档表明此RsaCryptoServiceProvider类不是线程安全的.因此,如果给出一些X.509证书,我需要在多个线程上执行非对称加密(通常在Web服务器上),创建RsaCryptoServiceProvider的多个实例的最佳方法是什么?

X509Certificate2上的私钥未标记为可导出,因此我不能简单地在原始RsaCryptoServiceProvider上导出参数并将其重新导入另一个实例以解决线程安全问题.

我通过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);
        }
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读