为什么 X509Certificate2 有时无法从 blob 创建?
我有一个 ASP.NET Web 服务,它正在接收一个字节数组,该数组表示包含 X.509 证书的 .pfx
文件的内容。 服务器端代码使用 System.Security.Cryptography.X509Certificate2
构造函数从字节加载证书:
X509Certificate2 native_cert = new X509Certificate2(
pkcs12_buf /*byte array*/,
password,
X509KeyStorageFlags.PersistKeySet |
X509KeyStorageFlags.Exportable
);
根据我的服务进程运行的身份,此调用要么成功,要么失败“内部错误”异常。 异常堆栈上的最后一个调用是 X509Utils._LoadCertFromBlob
,它是 mscore.dll
中的非托管代码。
当使用服务帐户的凭据在交互式登录中从控制台应用程序运行时,此代码会成功。 当在使用服务帐户凭据的应用程序池中的 w3wp.exe
下运行时,它会失败。 将应用程序池身份更改为管理员可以解决问题,因此这一定是权限问题,但我不知道为此需要什么权限。 该代码不涉及文件系统或 Windows 证书存储。
[更新:更多信息]
此错误出现在 Windows 事件日志中:
*Cryptographic Parameters:*
**Provider Name:** Microsoft Software Key Storage Provider
**Algorithm Name:** Not Available.
**Key Name:** {E182E13B-166D-472A-A24A-CBEF0808E9ED}
**Key Type:** User key.
*Cryptographic Operation:*
**Operation:** Open Key.
**Return Code:** 0x2
有什么想法吗?
I have an ASP.NET web service which is receiving a byte array representing the contents of a .pfx
file containing an X.509 certificate. The server-side code is using the System.Security.Cryptography.X509Certificate2
constructor to load the certificate from the bytes:
X509Certificate2 native_cert = new X509Certificate2(
pkcs12_buf /*byte array*/,
password,
X509KeyStorageFlags.PersistKeySet |
X509KeyStorageFlags.Exportable
);
Depending on who my service process is running as, this call will either succeed, or fail with an "internal error" exception. The last call on the exception stack is to X509Utils._LoadCertFromBlob
, which is unmanaged code in mscore.dll
.
This code succeeds when run from a console application in an interactive login using the service account's credentials. It fails when running under w3wp.exe
in an application pool that uses the service account's credentials. Changing the app pool identity to an administrator fixes the problem, so it must be a privilege issue, but I have no idea what privilege could be necessary for this. The code does not touch either the filesystem or the Windows certificate stores.
[UPDATE: More Info]
This error appears in the Windows Event Log:
*Cryptographic Parameters:*
**Provider Name:** Microsoft Software Key Storage Provider
**Algorithm Name:** Not Available.
**Key Name:** {E182E13B-166D-472A-A24A-CBEF0808E9ED}
**Key Type:** User key.
*Cryptographic Operation:*
**Operation:** Open Key.
**Return Code:** 0x2
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我自己刚刚找到了这个问题的解决方案:
这里的技巧是使用本地密钥存储
MachineKeySet
标志而不是用户配置文件密钥存储,如果您不指定替代位置,则这是默认值。 由于 ASP.NET 进程标识不会加载用户配置文件存储,因此以编程方式导入证书时无法访问该存储,但可以访问计算机存储。我认为 PersistKeySet 只是保持私钥加载,但我不确定它到底做了什么 - 如果您出于某种原因需要访问私钥,则这是必需的。
I just found the solution to this one myself:
The trick here is to use the local key store
MachineKeySet
flag instead of the user profile key store, which is the default if you don't specify an alternative location. Because the ASP.NET process identity doesn't load the user profile store, you can't access the store when importing a certificate programmatically, but you can access the machine store.I think
PersistKeySet
just keeps the private key loaded, but I'm not sure exactly what it does - it's required if you need to access the private key for some reason though.尝试向以下文件夹授予 ASP.NET 帐户权限:
C:\Documents And Settings\All Users\Microsoft\Crypto\RSA\MachineKeys\
(可能会根据您的环境而有所不同)Try granting the ASP.NET account permissions to the following folder:
C:\Documents And Settings\All Users\Microsoft\Crypto\RSA\MachineKeys\
(may vary according to your environment)