我在调用 GetRSAPrivateKey 时收到指定的无效提供程序类型

问题描述

我有一项使用私钥进行加密的服务。当我授予服务管理权限时,它可以工作。使用普通权限,它不会。调用 GetRSAPrivateKey() 时收到错误“指定的提供程序类型无效”。

var data = Convert.FromBase64String(cipherText);
var dataList = data.ToList();

using (var store = new X509Store(StoreName.TrustedPublisher,StoreLocation.LocalMachine))
using (var aesProvider = new AesCryptoServiceProvider())
{
    store.Open(OpenFlags.ReadOnly);
    byte[] key;
    using (var cert = store.Certificates.Find(X509FindType.FindBySubjectName,CertificateName,false)[0])
    {
        var publicKey = cert.GetRSAPublicKey();
        var encryptLength = publicKey.Encrypt(Encoding.UTF8.GetBytes("xxxxxxx"),RSAEncryptionPadding.OaepSHA512).Length;
        var encryptedKey = dataList.Take(encryptLength).ToArray();
        dataList.RemoveRange(0,encryptLength);
        var privateKey = cert.GetRSAPrivateKey();
        key = privateKey.Decrypt(encryptedKey,RSAEncryptionPadding.OaepSHA512);
    }

如果密钥不存在,则在安装过程中以编程方式将其添加到存储中。

var rsa = RSA.Create(2048);
var request = new CertificateRequest($"cn={CertificateName}",rsa,HashAlgorithmName.SHA512,RSASignaturePadding.Pkcs1);
var cert = request.CreateSelfSigned(DateTimeOffset.Now,DateTimeOffset.Now.AddYears(50));
File.WriteallBytes("c:\\temp\\EncryptionCert.pfx",cert.Export(X509ContentType.Pfx,_certificatePassword));
store.Open(OpenFlags.ReadWrite);
using (var cert = new X509Certificate2("c:\\temp\\EncryptionCert.pfx",_certificatePassword,X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet))
{
    store.Add(cert);
}

是否有允许访问证书存储的非管理员帐户设置,或者我在加载它时在代码中做错了什么?

解决方法

只有管理员和本地系统才能访问本地机器存储中的密钥。对于在不同安全上下文下运行的客户端应用程序,应使用 CurrentUser\My 存储。并且不要使用除 My 之外的任何其他存储来存储带有私钥的证书。否则,当来自本地机器存储的密钥向下传播到系统上的所有用户时,您可能会打开一个漏洞。只有 My 商店不会传播给其他用户。