“内部错误发生。”当加载 pfx 文件与 X509證 icate2

我尝试使用自签名证书(c #) :

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

在一个共享的网站托管服务器上,我得到了一个错误:

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 文件的原因是我需要一个私钥访问权限(cerfile 加载 OK)。 我在我的开发机器上做了这样的 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版本

53192 次浏览

使用本地计算机存储区获取私钥:

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

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

即使从磁盘读取证书并将其存储在对象中,私钥仍然存储在 Microsoft 加密 API 加密服务提供程序密钥数据库中。在宿主服务器上,ASP.NET 进程没有访问用户存储区的权限。

另一种方法(根据下面的一些注释)是修改 IIS 配置或 AppPool 标识——它们可以工作。但是,这里假设存在对这些配置项的访问,而实际情况可能并非如此(例如,在共享主机环境中)。

我尝试了 Randy 的解决方案,把它改成 MachineKeySet,但是得到了错误信息:

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

因此,我在谷歌上搜索了一下,发现了一个帖子,建议将其改为:

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

这就解决了我的问题。

我还没有尝试在 IIS 配置中更改设置应用程序池设置的建议。要做到这一点,到高级设置为您的网站的应用程序池,然后设置“加载用户配置文件”为真。当此设置为 false 时,显然无法访问密钥容器。