专用密钥扔类型System.Security.Cryptography.CryptographicException的异常

问题描述:

我尝试使用下面的代码使用自签名证书:专用密钥扔类型System.Security.Cryptography.CryptographicException的异常

X509Certificate2 cert = ToCertificate("CN=localhost"); 


public static X509Certificate2 ToCertificate(this string subjectName, 
               StoreName name = StoreName.My, 
               StoreLocation location = StoreLocation.LocalMachine 
               ) 
    { 
     X509Store store = new X509Store(name, location); 

     store.Open(OpenFlags.ReadOnly); 

     try 
     { 
      var cert = store.Certificates.OfType<X509Certificate2>().FirstOrDefault(c => c.Subject.Equals(subjectName, StringComparison.OrdinalIgnoreCase)); 

      return cert != null ? new X509Certificate2(cert) : null; 
     } 
     catch (Exception) 
     { 

      throw; 
     } 
     finally 
     { 
      store.Certificates.OfType<X509Certificate2>().ToList().ForEach(c => c.Reset()); 
      store.Close(); 
     } 
    } 

我得到以下异常:

PrivateKey = 'cert.PrivateKey' threw an exception of type 'System.Security.Cryptography.CryptographicException' 

enter image description here

我试过this fix,并this fix

但仍然有问题!

+0

来自异常的信息是什么? – bartonjs

+0

@bartonjs消息:“指定的提供程序类型无效。\ r \ n” 来源:“mscorlib” –

+0

请运行'certutil -store -silent -v my localhost'并共享结果。 (如果你想要有选择性,“公钥算法”和“CERT_KEY_PROV_INFO_PROP_ID(2):”是重要的;但它没有打印任何内容应该是秘密的) – bartonjs

听起来像您的证书使用CNG密钥存储来存储私钥。在这种情况下,PrivateKey属性将在尝试访问该属性时抛出此异常。

为了正确地访问密钥,则必须使用扩展方法来访问键:https://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate2(v=vs.110).aspx#Extension方法

此外,访问任何私钥存储类型时,无论是遗留(CSP)或优选这些扩展方法CNG。也就是说,不要直接访问PrivateKeyPublicKey属性,而是通过这些方法访问它们。

+0

我将项目升级到.net framework 4.6.1,其中这些扩展方法被定义但仍然有相同的错误。 –

davidchristiansen说:

什么是CNG密钥? Windows中的证书使用存储提供程序进行存储。 Windows有两个这样的提供者,它们不兼容。旧式“加密服务提供商”或简称CSP和新型“加密API:下一代”或CNG。自从Windows Vista开始,CNG提供商就已经出现,虽然它更安全,更易于使用,但许多方面的软件仍然与CNG提供商不兼容。这似乎也包括.NET Framework。

对此可能的解决方法可能是直接使用CryptoAPI/CNG API来处理CNG密钥。但是如果我们想要一个更容易理解CNG的纯净.NET解决方案,我们需要找到另一种解决方案(详情请参阅!)。

我跟随了以下帖子转换为将我的证书密钥从CNG转换为RSA。有用!

http://blog.davidchristiansen.com/2016/05/521/