Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么X509Certificate2有时无法从blob创建?_C#_Blob_X509certificate2 - Fatal编程技术网

C# 为什么X509Certificate2有时无法从blob创建?

C# 为什么X509Certificate2有时无法从blob创建?,c#,blob,x509certificate2,C#,Blob,X509certificate2,我有一个ASP.NET web服务,它接收一个字节数组,表示包含X.509证书的.pfx文件的内容。服务器端代码正在使用System.Security.Cryptography.X509Certificate2构造函数从字节加载证书: X509Certificate2 native_cert = new X509Certificate2( pkcs12_buf /*byte array*/, password,

我有一个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.\u 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  

有什么想法吗?

尝试将ASP.NET帐户权限授予以下文件夹:
C:\Documents And Settings\All Users\Microsoft\Crypto\RSA\MachineKeys\
(可能因您的环境而异)

我自己刚刚找到了解决此问题的方法:

X509KeyStorageFlags flags = X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet;

X509Certificate2 cert = new X509Certificate2(pkcs12_buf, password, flags);
这里的诀窍是使用本地密钥存储
MachineKeySet
标志,而不是用户配置文件密钥存储,如果不指定替代位置,这是默认设置。由于ASP.NET进程标识不加载用户配置文件存储,因此以编程方式导入证书时无法访问存储,但可以访问计算机存储


我认为,
PersistKeySet
只是让私钥保持加载状态,但我不确定它到底是做什么的——如果出于某种原因需要访问私钥,它是必需的。

我认为您的思路是正确的,但它似乎没有试图访问文件系统。成功访问用户个人配置文件下的Microsoft\Crypto\RSA的帐户(不是AllUsers)。根据procmon的说法,失败的一个是甚至没有尝试访问文件系统。这个权限更改在Win2k8上对我有效。为我节省了大量调试时间。谢谢为什么您运行的ASP.Net用户上下文不能访问自己的存储?(这确实解决了我的问题-这是一个经典的“但它在我的开发机器上工作!只是对推理很好奇。)