.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
Это скажет вам, какой процесс / пользователь сделал операцию удаления... и, возможно, этого будет достаточно, чтобы определить, что пошло не так.
Вы можете предположить, что идентификация файла закрытого ключа и регистрация аудита выполняются более программно; но это был самый быстрый способ, которым я знал, чтобы объяснить это.