jle*_*lew 10 c# blob x509certificate2
我有一个ASP.NET Web服务,它接收一个字节数组,表示.pfx包含X.509证书的文件的内容.服务器端代码使用System.Security.Cryptography.X509Certificate2构造函数从字节加载证书:
X509Certificate2 native_cert = new X509Certificate2(
pkcs12_buf /*byte array*/,
password,
X509KeyStorageFlags.PersistKeySet |
X509KeyStorageFlags.Exportable
);
Run Code Online (Sandbox Code Playgroud)
根据我的服务进程的运行方式,此调用将成功,或者因"内部错误"异常而失败.对异常堆栈的最后一次调用是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
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
我自己刚刚找到了这个解决方案:
X509KeyStorageFlags flags = X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet;
X509Certificate2 cert = new X509Certificate2(pkcs12_buf, password, flags);
Run Code Online (Sandbox Code Playgroud)
这里的技巧是使用本地密钥存储MachineKeySet标志而不是用户配置文件密钥存储区,如果您没有指定备用位置,则这是默认值.由于ASP.NET进程标识未加载用户配置文件存储,因此在以编程方式导入证书时无法访问存储,但您可以访问计算机存储.
我认为PersistKeySet只是保持加载私钥,但我不确定它究竟是做什么的 - 如果您出于某种原因需要访问私钥,则需要它.