我正在尝试使用自签名证书(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文件的原因是因为我需要私钥访问(cer文件加载好)。 我在我的dev mochine上制作了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版本
答案 0 :(得分:138)
使用本地计算机商店获取私钥:
X509Certificate2 cert = new X509Certificate2("myhost.pfx", "pass",
X509KeyStorageFlags.MachineKeySet);
MachineKeySet
被描述为“私钥存储在本地计算机存储中而不是当前用户存储中”。没有标志的默认值将放在用户存储中。
即使您从磁盘读取证书并将其存储在对象中,私钥仍存储在Microsoft Cryptographic API加密服务提供程序密钥数据库中。在托管服务器上,ASP.NET进程无权访问用户存储。
另一种方法(根据下面的一些评论)是修改IIS配置或应用程序池标识 - 它确实有效。但是,这假设可以访问这些配置项,但可能并非如此(例如,在共享托管环境中)。
答案 1 :(得分:10)
我尝试过Randy将其更改为MachineKeySet的解决方案,但后来收到了错误消息:
“密钥无法在指定状态下使用”
所以经过一番谷歌搜索后,我发现了一个帖子,建议将其更改为:
var certificate = new X509Certificate2(certKeyFilePath, passCode,
X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.PersistKeySet );
这解决了我的问题。
我还没有尝试过更改IIS配置中的设置应用池设置的建议。要执行此操作,请转到站点应用程序池的“高级设置”,然后将“加载用户配置文件”设置为true。如果此设置为false,则无法显示密钥容器。