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

时间:2009-02-17 19:39:49

标签: c# blob x509certificate2

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

有什么想法吗?

2 个答案:

答案 0 :(得分:9)

我自己刚刚找到了解决方案:

X509KeyStorageFlags flags = X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet;

X509Certificate2 cert = new X509Certificate2(pkcs12_buf, password, flags);

这里的技巧是使用本地密钥库MachineKeySet标志而不是用户配置文件密钥库,如果您未指定备用位置,则这是默认值。由于ASP.NET进程标识未加载用户配置文件存储,因此在以编程方式导入证书时无法访问存储,但您可以访问计算机存储。

我认为PersistKeySet只是保持加载私钥,但我不确定它的作用 - 如果你出于某种原因需要访问私钥,则需要它。

答案 1 :(得分:2)

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