“X509Certificate2”加载pfx文件时发生“内部错误”

我试图使用自签名证书(C#):

X509Certificate2 cert = new X509Certificate2( Server.MapPath("~/App_Data/myhost.pfx"), "pass"); 

在一个共享的networking托pipe服务器,我得到一个错误:

 System.Security.Cryptography.CryptographicException: An internal error occurred. 

堆栈跟踪结束

 System.Security.Cryptography.CryptographicException. ThrowCryptogaphicException(Int32 hr) +33 System.Security.Cryptography.X509Certificates.X509Utils. _LoadCertFromFile(String fileName, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx) +0 System.Security.Cryptography.X509Certificates.X509Certificate. LoadCertificateFromFile(String fileName, Object password, X509KeyStorageFlags keyStorageFlags) +237 System.Security.Cryptography.X509Certificates.X509Certificate2..ctor( String fileName, String password) +131 

在我的开发机器上它加载好。 之所以我加载* .pfx不是* .cer文件,因为我需要一个私钥访问(cer文件加载好)。 我在这个开发系统上做了pfx:

 makecert -r -n "CN=myhost.com, E=admin@myhost.com" -sky exchange -b 01/01/2009 -pe -sv myhost.pvk myhost.cer <b>pvk2pfx</b> -pvk myhost.pvk -spc myhost.cer -pfx myhost.pfx -po pass</code> 

我正在使用makecert版本v5.131.3790.0

使用本地计算机存储专用密钥:

 X509Certificate2 cert = new X509Certificate2("myhost.pfx", "pass", X509KeyStorageFlags.MachineKeySet); 

MachineKeySet被描述为“私钥存储在本地计算机存储中而不是当前用户存储”。 没有标志的默认值是放在用户存储区中。

即使您正在从磁盘读取证书并将其存储在对象中,私钥仍存储在Microsoft Cryptographic API Cryptographic Service Provider密钥数据库中。 在托pipe服务器上,ASP.NET进程没有访问用户存储的权限。

另一种方法(根据下面的一些评论)是修改IISconfiguration或应用程序池身份 – 哪些工作。 但是,这假定有访问这些configuration项目可能不是这种情况(例如在共享主机环境中)。

我试过Randy的解决scheme,将其更改为MachineKeySet,但后来得到错误消息:

“密钥在指定状态下无效”

所以在search一下后,我发现一个post,build议将其更改为:

 var certificate = new X509Certificate2(certKeyFilePath, passCode, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet ); 

这整理了我的问题。

我还没有尝试在IISconfiguration中更改设置应用程序池设置的build议。 要做到这一点去你的网站的应用程序池的高级设置,然后设置“加载用户configuration文件”为true。 当此设置为false时,密钥容器显然不可访问。