【问题标题】:.NET Core X509Certificate2.PrivateKey throws nte_bad_keyset error.NET Core X509Certificate2.PrivateKey 抛出 nte_bad_keyset 错误
【发布时间】:2017-05-19 16:25:58
【问题描述】:

当尝试使用以下代码从X509Store 获取X509Certificate2 对象时:

    private X509Certificate2 GetKey()
    {
        try
        {
            X509Store store = new X509Store("WebHosting", StoreLocation.LocalMachine);
            store.Open(OpenFlags.ReadOnly);
            var collection = store.Certificates.Find(X509FindType.FindBySubjectName, "xxxxxxx", true);

            if (collection.Count == 0)
            {
                throw new Exception("No keys matched");
            }

            if (collection.Count > 1)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("More than 1 key matched:\r\n");

                foreach (var cert in collection)
                {
                    sb.Append($"{cert.SubjectName} - {cert.Thumbprint}\r\n");
                }
                throw new Exception(sb.ToString());
            }

            return collection[0];
        }
        catch (Exception ex)
        {
            // something really bad happened, log it
            Logger.LogException(ex);
            throw;
        }
    }

我成功拿到了钥匙;但是,当尝试使用 key.PrivateKey 获取对象中的私钥时,我收到以下错误:OpenCSP failed with error code 2148073494. 查找 Windows 错误 2148073494,我收到 nte_bad_keyset。看起来在其他情况下出现了错误,引发了同样的错误here,但他们已经修复了该错误。当我在控制台应用程序中运行这段代码时,它可以正常工作,并且在我在 IISExpress 下运行的测试环境中也可以正常工作。在 IIS 下的生产环境中运行时,我每次都会收到此错误。我试过在管理员用户的上下文中运行,只是为了确保这不是一个奇怪的权限错误,同样的事情。根据我对这个 Windows 错误的理解,Windows 给了我密钥所在的位置,然后告诉我那个地址没有任何东西。我为此使用"System.Security.Cryptography.Algorithms": "4.3.0"

编辑:我应该注意,作为我的测试的一部分,我实际上从生产环境中获取了我正在寻找的确切证书到我的测试环境中并且它加载得很好。我还在生产环境中运行控制台应用程序,拉取相同的密钥,它运行良好。

【问题讨论】:

  • 证书是如何进入生产机器的?如果您使用 .NET 读取 PFX 并将其添加到证书存储区,但在加载 PFX 时未设置 X509KeyStorageFlags.PersistKeySet 标志,您最终会得到此行为(在密钥“未持久化”之后)。
  • 我不使用 .NET 将证书添加到商店。 PFX 文件被添加到商店并通过 ACME 应用程序更新。这是一个完全独立的过程,不属于我的项目。
  • 您确定您的 IIS 应用程序池用户有权访问此证书的私钥吗?

标签: c# .net-core private-key x509certificate2


【解决方案1】:

最终,答案是“在将私钥导入证书存储后删除了某些东西”(或者,可能会混淆 Windows,使其记住密钥所在的位置,尽管它实际上并不存在于那里)。

例如,如果您知道它会工作一会儿然后停止:

> certutil -store my
...
================ Certificate 6 ================
Serial Number: 3451b93c10f9279348a949f729d1ff10
Issuer: CN=localhost
 NotBefore: 1/26/2015 2:19 PM
 NotAfter: 1/25/2020 4:00 PM
Subject: CN=localhost
Signature matches Public Key
Root Certificate: Subject matches Issuer
Template:
Cert Hash(sha1): 15 e3 4c d3 2d a7 54 99 a9 17 8f 17 26 25 63 25 8f 3a 94 28
  Key Container = IIS Express Development Certificate Container
  Unique container name: fad662b360941f26a1193357aab3c12d_1fcb2e07-cec4-4ba1-9c78-58a431e1aefd
  Provider = Microsoft RSA SChannel Cryptographic Provider
Encryption test passed
CertUtil: -store command completed successfully.

看到它在“Microsoft RSA SChannel Cryptographic Provider”中,转到https://msdn.microsoft.com/en-us/library/windows/desktop/bb204778(v=vs.85).aspx 并看到密钥文件将位于%ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\RSA\MachineKeysUnique container name 恰好是它将拥有的文件的名称。

所以,打开该目录,右键单击该文件。

  • 属性
  • 安全选项卡
  • 高级按钮
  • 审核选项卡
  • 编辑按钮
  • 添加按钮
  • 输入“Everyone”,按“Check Names”,选择“Everyone”,点击 OK,点击 OK。
  • 检查删除:成功。
  • 点击 OK 关闭所有对话框。

稍后,在您开始收到密钥集错误后,在安全日志中搜索文件删除审计(来自安全审计的事件 4663):

An attempt was made to access an object.

Subject:
    Security ID:        SOMEDOMAIN\theaccount
    Account Name:       theaccount
    Account Domain:     SOMEDOMAIN
    Logon ID:       0xabcdef

Object:
    Object Server:  Security
    Object Type:    File
    Object Name:    C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys\fad662b360941f26a1193357aab3c12d_1fcb2e07-cec4-4ba1-9c78-58a431e1aefd
    Handle ID:  0xef8

Process Information:
    Process ID: 0xf54
    Process Name:   C:\Windows\explorer.exe

Access Request Information:
    Accesses:   DELETE

    Access Mask:    0x10000

这将告诉您执行删除操作的进程/用户...也许这足以确定出了什么问题。

您大概可以通过更编程的方式进行私钥文件识别和审计注册;但这是我所知道的最快的解释方式。

【讨论】:

  • 我尝试了您的建议,没有任何区别,并且证书周围没有单个事件日志条目。我不明白如何在网站无法访问密钥的同时删除密钥,我的测试应用程序可以。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-09
  • 2021-01-22
  • 2020-05-04
  • 1970-01-01
  • 2018-02-21
  • 1970-01-01
相关资源
最近更新 更多