.NET Core X509Certificate2.PrivateKey выбрасывает ошибку nte_bad_keyset

При попытке получить X509Certificate2 объект из X509Store используя следующий код:

    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, Похоже, что были ошибки в других ситуациях, которые выдают эту же ошибку здесь, но они закрыли эту ошибку как исправленную. Когда я запускаю этот фрагмент кода в консольном приложении, он отлично работает, а также отлично работает в моей тестовой среде, работающей под управлением IISExpress. При запуске в производственной среде под IIS я каждый раз получаю эту ошибку. Я попытался запустить в контексте пользователя с правами администратора, чтобы убедиться, что это не странная ошибка разрешения, то же самое. Из того, что я понимаю об этой ошибке Windows, является то, что Windows дала мне место, где находится ключ, а затем сказала, что по этому адресу ничего нет. я использую "System.Security.Cryptography.Algorithms": "4.3.0" за это.

РЕДАКТИРОВАТЬ: я должен отметить, что как часть моего тестирования, я фактически взял точный сертификат, который я ищу из производственной среды в моей тестовой среде, и он загрузился нормально. Я также запустил консольное приложение в производственной среде, потянув тот же ключ, и оно работало нормально.

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", перейдите на https://msdn.microsoft.com/en-us/library/windows/desktop/bb204778(v=vs.85).aspx и убедитесь, что файл ключа будет находиться в %ALLUSERSPROFILE%\Application Data\Microsoft\Crypto\RSA\MachineKeys, Unique container name бывает имя файла, который он будет иметь.

Итак, откройте этот каталог, щелкните правой кнопкой мыши на файле.

  • свойства
  • Вкладка "Безопасность"
  • Расширенная кнопка
  • Вкладка Аудит
  • Кнопка редактирования
  • Добавить кнопку
  • Введите "Все", нажмите "Проверить имена", выберите "Все", нажмите ОК, нажмите ОК.
  • Проверьте Удалить: Успех.
  • Нажмите OK, чтобы закрыть все диалоги.

Позже, после того, как вы начнете получать ошибки набора ключей, найдите в журнале безопасности проверку на удаление файла (событие 4663 из Security-Auditing):

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

Это скажет вам, какой процесс / пользователь сделал операцию удаления... и, возможно, этого будет достаточно, чтобы определить, что пошло не так.

Вы можете предположить, что идентификация файла закрытого ключа и регистрация аудита выполняются более программно; но это был самый быстрый способ, которым я знал, чтобы объяснить это.

Другие вопросы по тегам