«Указан неверный тип провайдера» CryptographicException при попытке загрузить закрытый ключ сертификата
Я пытаюсь прочитать закрытый ключ сертификата, который был предоставлен мне сторонним поставщиком услуг, поэтому я могу использовать его для шифрования некоторого XML-кода перед его отправкой по беспроводной сети. Я делаю это программно в C #, но я думаю, что это проблема с разрешениями или неправильной настройкой, поэтому я сосредоточусь на фактах, которые кажутся наиболее актуальными:
Я не думаю, что эта проблема связана с кодом; мой код работает на других компьютерах, и проблема затрагивает пример кода от Microsoft.Сертификат был предоставлен в виде файла PFX и предназначен только для целей тестирования, поэтому он также включает в себя фиктивный центр сертификации.Используя MMC.exe, я могу импортировать сертификат в персональное хранилище для локального компьютера, прежде чем предоставлять разрешения на закрытый ключ всем соответствующим учетным записям и перетаскивать центр сертификации в доверенные корневые центры сертификации.Используя C #, я могу загрузить сертификат (идентифицированный его отпечатком большого пальца) и проверить, что у него есть закрытый ключ, используяX509Certificate2.HasPrivateKey
, Однако попытка прочитать ключ вызывает ошибку. В .NETCryptographicException
выдается сообщение «Указан неверный тип провайдера» при попытке доступа к свойствуX509Certificate2.PrivateKey
, В Win32 вызывается методCryptAcquireCertificatePrivateKey
возвращает эквивалент HRESULT,NTE_BAD_PROV_TYPE
.Это то же исключение, которое также возникает при использовании двух собственных примеров кода Microsoft для чтения закрытого ключа сертификата.Установка того же сертификата в эквивалентное хранилище для текущего пользователя вместо локального компьютера позволяет успешно загрузить закрытый ключ.Я на Windows 8.1 с правами локального администратора, и я попытался запустить мой код в обычном и повышенном режимах. Коллеги в Windows 7 и Windows 8 смогли загрузить ключ из локального хранилища компьютеров для того же сертификата.Я могу успешно прочитать закрытый ключ самозаверяющего сертификата IIS, который находится в том же хранилище.Я уже нацеливаюсь на .NET 4.5 (об этой ошибке сообщалось в некоторых старых версиях фреймворка).Я не думаю, что это проблема с шаблонами сертификатов, потому что я ожидаю, что это повлияет как на локальный компьютер, так и на хранилища текущего пользователя?В отличие от моих коллег, я несколько раз пытался удалить и переустановить сертификат различными способами, в том числе с помощью диспетчера IIS, а также с использованием более старого сертификата того же эмитента. Я не вижу следов старых или дублирующих сертификатов в MMC. Однако у меня есть много файлов с закрытым ключом одинакового размера, которые, исходя из времени последней записи, должны были остаться после моих различных попыток установки. Они находятся в следующих местах для локального компьютера и текущего хранилища пользователей соответственно:
C: \ ProgramData \ Microsoft \ Crypto \ RSA \ MachineKeys
c: \ Users \\ AppData \ Roaming \ Microsoft \ Crypto \ RSA \ S-1-5-21- [оставшийся идентификатор пользователя]
Итак, кто-нибудь может посоветовать, пожалуйста:
Рекомендуется удалить сертификат с помощью MMC, удалить все файлы, которые выглядят как потерянные закрытые ключи, а затем переустановить сертификат и повторить попытку?Есть ли другие файлы, которые я должен попытаться удалить вручную?Есть что-нибудь еще, что я должен попробовать?ОБНОВЛЕНИЕ - Добавлен пример кода, показывающий попытку чтения закрытого ключа:
static void Main()
{
// Exception occurs when trying to read the private key after loading certificate from here:
X509Store store = new X509Store("MY", StoreLocation.LocalMachine);
// Exception does not occur if certificate was installed to, and loaded from, here:
//X509Store store = new X509Store("MY", StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
X509Certificate2Collection fcollection = (X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
X509Certificate2Collection scollection = X509Certificate2UI.SelectFromCollection(fcollection, "Test Certificate Select", "Select a certificate from the following list to get information on that certificate", X509SelectionFlag.MultiSelection);
Console.WriteLine("Number of certificates: {0}{1}", scollection.Count, Environment.NewLine);
foreach (X509Certificate2 x509 in scollection)
{
try
{
Console.WriteLine("Private Key: {0}", x509.HasPrivateKey ? x509.PrivateKey.ToXmlString(false) : "[N/A]");
x509.Reset();
}
catch (CryptographicException ex)
{
Console.WriteLine(ex.Message);
}
}
store.Close();
Console.ReadLine();
}