代码之家  ›  专栏  ›  技术社区  ›  jlew

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

  •  10
  • jlew  · 技术社区  · 16 年前

    我有一个ASP.NET Web服务,它接收一个表示 .pfx 包含X.509证书的文件。服务器端代码正在使用 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 回复  |  直到 9 年前
        1
  •  9
  •   Luiso Rahul    9 年前

    我自己也找到了解决办法:

    X509KeyStorageFlags flags = X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet;
    
    X509Certificate2 cert = new X509Certificate2(pkcs12_buf, password, flags);
    

    这里的诀窍是使用本地密钥存储 MachineKeySet 标记而不是用户配置文件密钥存储区,如果不指定其他位置,则默认设置为该存储区。由于ASP.NET进程标识不加载用户配置文件存储,因此在以编程方式导入证书时无法访问存储,但可以访问计算机存储。

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

        2
  •  2
  •   Darin Dimitrov    16 年前

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