В деталях, есть номер сертификата криптопро, нужно понять доступен ли к нему ключ.
Самый простой способ. из умозрительного — попробовать создать подпись или еще что-нибудь, но может можно просто чекнуть есть/нет?
SOLUTION: Чтобы определить доступность закрытого ключа в .net нужно 1) установить крипто про .net 2) .net должен быть определенной версии (по информации с форума), точно ниже 4.8(не работает)
В итоге решение такое(крипто про 5). получаем список доступных контейнеров и экспортируем из них сертификаты. по серику определяем доступен ли контейнер ЗК нужного серта.
var cp_root = @"C:\Program Files\Crypto Pro\CSP";
if (!TryExecute(Path.Combine(cp_root, "csptest.exe"), "-keyset -enum_cont -verifycontext -fqcn -machinekeys", handleError, out var output))
{
handleLog?.Invoke("csptest failed.");
return false;
}
var containers = output.Where(x => x.StartsWith(@"\\.\"));
foreach (var container in containers)
{
handleLog?.Invoke($"found container = {container}");
var cert_path = Path.GetTempFileName();
for_delete.Add(cert_path);
if (!TryExecute(Path.Combine(cp_root, "certmgr.exe"), $"-export -container \"{container}\" -certificate -dest \"{cert_path}\" -silent", handleError, out _))
{
handleLog?.Invoke($"container = \"{container}\" to \"{cert_path}\" failed.");
continue;
}
X509Certificate2 certToFind = new X509Certificate2();
certToFind.Import(File.ReadAllBytes(cert_path));
PS покопался еще в теме. Оказалось Bouncy Castle вроде бы поддерживает наши госты. насчет разрешения фстэк не знаю. но вот проблема не нашел у них простого способа получить инфу о контейнере.
т.е. идут ссылки на апи винды, а винда(дотнет) не может опять таки отдать закрытый ключ из-за незнания гостов. и вот непонятно до конца, если смотреть глазами на личный серт, то видим отметку есть закрытый ключ,
даже если контейнер недоступен. т.е. все же в свойствах серта прописала ссылка на физический путь к контейнеру или просто признак что ключ где-то есть?
Вообщем непонятно как Bouncy Castle обращается к закрытому ключу на контейнере(видел только варианты с загрузкой прямой из файла). надо поэкспериментировать.
Здравствуйте, varenikAA, Вы писали:
AA>В деталях, есть номер сертификата криптопро, нужно понять доступен ли к нему ключ. AA>Самый простой способ. из умозрительного — попробовать создать подпись или еще что-нибудь, но может можно просто чекнуть есть/нет?
Если номер это SerialNumber, то находишь сертификат по этому номеру, и проверяешь у него поле PrivateKey на null.
Re[2]: Как определить доступность закрытого ключа к сертификату по номеру
Здравствуйте, amironov79, Вы писали:
A>Здравствуйте, varenikAA, Вы писали:
AA>>В деталях, есть номер сертификата криптопро, нужно понять доступен ли к нему ключ. AA>>Самый простой способ. из умозрительного — попробовать создать подпись или еще что-нибудь, но может можно просто чекнуть есть/нет?
A>Если номер это SerialNumber, то находишь сертификат по этому номеру, и проверяешь у него поле PrivateKey на null.
Решил апнуть тему. с крипто про не работает. при обращению к privateKey ошибка "алгоритм не поддерживается".
.net 4.8
нужно очень
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[3]: Как определить доступность закрытого ключа к сертификату по номеру
Здравствуйте, vaa, Вы писали:
vaa>Решил апнуть тему. с крипто про не работает. при обращению к privateKey ошибка "алгоритм не поддерживается". vaa> .net 4.8
Вам нужен сам PrivateKey или только факт его наличия?
Если второе, то вроде бы достаточно смотреть на свойство HasPrivateKey
Если же вам нужны какие-то манипуляции с закрытым ключом, то по-моему, без КриптоПро .NET вы ничего сделать не сможете (если ничего не путаю, как минимум он добавляет поддержку тех самых алгоритмов, на которые у вас сейчас идет ругань).
Re[4]: Как определить доступность закрытого ключа к сертификату по номеру
Здравствуйте, Михаил Романов, Вы писали:
МР>Здравствуйте, vaa, Вы писали:
vaa>>Решил апнуть тему. с крипто про не работает. при обращению к privateKey ошибка "алгоритм не поддерживается". vaa>> .net 4.8
МР>Вам нужен сам PrivateKey или только факт его наличия?
что ключ реально доступен(воткнут в пк).
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[5]: Как определить доступность закрытого ключа к сертификату по номеру
Здравствуйте, vaa, Вы писали:
vaa>что ключ реально доступен(воткнут в пк).
Тогда HasPrivateKey не подойдет, он только фиксирует, что у текущего открытого ключа есть где-то парный закрытый (в реестре или на внешнем носителе — уже детали).
Вариант обратиться к закрытому ключу или попытаться выполнить криптооперацияю боюсь приведет к тому, что криптопрошный провайдер посмотрит место хранения криптоконтейнера и, если такой носитель не представлен, покажет своё окошко "Вставьте токен XXX".
И, имхо, работая через стандартные API (те, которые вынесены в .Net) это не обойти. Там нужен доступ к API криптоконтейнеров, но он в Managed части хоть и есть в каком-то виде, но какой-то очень урезанный (представлены провайдеры конкретных типов ключей и только для 2-х стандартных алгоритмов).
Как я понимаю, вам нужно:
— получить имя криптоконтейнера для представленного сертификата (который вы нашли по serial number)
— проверить, что указанный контейнер сейчас доступен.
Ну или попробовать зайти с обратной стороны — получить все доступные криптоконтейнеры и проверить, есть ли среди них нужный, хотя это может быть не быстро.
Это можно сделать через CryptoAPI (я решал когда-то схожую задачу, работая через проприетарную обертку над CryptoAPI — пробежаться по криптоконтейнерам и найти нужный).
Вроде как упомянуты выше КриптоПро .Net такую задачу тоже позволяет решить.
Но решение не универсальное (завязанное на КриптоПро, хотя я не уверен, а у нас в стране остались другие поставщики?) и без указанной библиотеки не работает.
Re[6]: Как определить доступность закрытого ключа к сертифик
Здравствуйте, Михаил Романов, Вы писали:
МР>Здравствуйте, vaa, Вы писали:
МР>Но решение не универсальное (завязанное на КриптоПро, хотя я не уверен, а у нас в стране остались другие поставщики?) и без указанной библиотеки не работает.
спасибо за совет, крипто нет вроде платный,
пока сделал через через создание подписи кмс, не проверял еще будет ли блочить если контейнера нет,
вариант с поиском контейнеров пока не рассматривал еще думаю может утилиту консольную использовать там тоже есть различные функции она правда только с 5 крипто про идет.
PS посмотрел крипто про пример "Пример получения контейнера по файлу сертификата". Оказалось, что там чисто дотнетные функции используются и инфу CspKeyContainerInfo
получают из PrivateKey.
System.NotSupportedException: "Алгоритм ключа сертификата не поддерживается."
полазил по форуму крипто про. да, для примера нужно ставить клиента ихнего.
но все равно с 4.8 не работает)) при этом нужна какая-то особа версия выше которой ничего не будет работать.
вообщем план такой, cpstest выводит список доступных контэйнеров.
можно по ним опять же утилитой скопировать серт из контейнера в файл
ну а дальше загрузить в x509 и найти похожий в хранилище пользователя.
Здравствуйте, vaa, Вы писали:
vaa>Здравствуйте, Михаил Романов, Вы писали:
МР>>Здравствуйте, vaa, Вы писали:
МР>>Но решение не универсальное (завязанное на КриптоПро, хотя я не уверен, а у нас в стране остались другие поставщики?) и без указанной библиотеки не работает.
vaa>спасибо за совет, крипто нет вроде платный,
vaa>пока сделал через через создание подписи кмс, не проверял еще будет ли блочить если контейнера нет, vaa>вариант с поиском контейнеров пока не рассматривал еще думаю может утилиту консольную использовать там тоже есть различные функции она правда только с 5 крипто про идет.
vaa>PS посмотрел крипто про пример "Пример получения контейнера по файлу сертификата". Оказалось, что там чисто дотнетные функции используются и инфу CspKeyContainerInfo vaa>получают из PrivateKey.
vaa>
vaa>System.NotSupportedException: "Алгоритм ключа сертификата не поддерживается."
vaa>
vaa>полазил по форуму крипто про. да, для примера нужно ставить клиента ихнего. vaa>но все равно с 4.8 не работает)) при этом нужна какая-то особа версия выше которой ничего не будет работать.
vaa>вообщем план такой, cpstest выводит список доступных контэйнеров. vaa>можно по ним опять же утилитой скопировать серт из контейнера в файл vaa>ну а дальше загрузить в x509 и найти похожий в хранилище пользователя.
Криптопо net клиент поставили? У меня net 4.6.1 все прекрасно работает:
using System;
using System.Security.Cryptography.X509Certificates;
namespace ConsoleApp
{
internal class Program
{
private static string thumbprint = "07077755d7bba15d783dcb89f3fa6c1cc5a94bc2";
static void Main(string[] args)
{
var cer = GetCertificate(thumbprint);
if (cer.PrivateKey != null)
{
Console.WriteLine("Ключ есть");
}
else
{
Console.WriteLine("Ключа нету");
}
}
private static X509Certificate2 GetCertificate(string thumbprint)
{
using (var store = new X509Store("My", StoreLocation.CurrentUser))
{
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
var found =
store.Certificates.Find(X509FindType.FindByThumbprint,
thumbprint, false);
if (found.Count == 0)
{
throw new ArgumentException("Сертификат с отпечатком: " + thumbprint + " не найден.");
}
return found[0];
}
}
}
}
Программа – это мысли спрессованные в код
Re[8]: Как определить доступность закрытого ключа к сертифик
Здравствуйте, Qulac, Вы писали:
Q>Здравствуйте, vaa, Вы писали:
vaa>>Здравствуйте, Qulac, Вы писали:
Q>>>Криптопо net клиент поставили? У меня net 4.6.1 все прекрасно работает:
vaa>>да бесплатное с сайта. с 4.8 не работает.
Q>Пересобрал под 4.8 все ок.
System.NotSupportedException
HResult=0x80131515
Сообщение = Алгоритм ключа сертификата не поддерживается.
Источник = System
Трассировка стека:
at System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey()
at ConsoleApp1.Program.Main(String[] args) in C:\tmp\ConsoleApp1\Program.cs:line 26
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[11]: Как определить доступность закрытого ключа к сертифик
Здравствуйте, vaa, Вы писали:
vaa>Здравствуйте, Qulac, Вы писали:
Q>>Здравствуйте, vaa, Вы писали:
vaa>>>Здравствуйте, Qulac, Вы писали:
Q>>>>Криптопо net клиент поставили? У меня net 4.6.1 все прекрасно работает:
vaa>>>да бесплатное с сайта. с 4.8 не работает.
Q>>Пересобрал под 4.8 все ок.
vaa>.net 4.8 (win10 x86_64) vaa>крипто про .net клиент 1.0.8377.1 vaa>csp 5.0.12500
vaa>ключ сделал здесь https://www.cryptopro.ru/certsrv/certrmpn.asp
vaa>
vaa>System.NotSupportedException
vaa> HResult=0x80131515
vaa> Сообщение = Алгоритм ключа сертификата не поддерживается.
vaa> Источник = System
vaa> Трассировка стека:
vaa> at System.Security.Cryptography.X509Certificates.X509Certificate2.get_PrivateKey()
vaa> at ConsoleApp1.Program.Main(String[] args) in C:\tmp\ConsoleApp1\Program.cs:line 26
vaa>
Т.е. тут: Тоже сделал, все ок. Вводите имя, страна RU, ставим флажок "Пометить ключ как экспортируемый" остальные поля без изменений и нажимаем выдать.
Программа – это мысли спрессованные в код
Re[12]: Как определить доступность закрытого ключа к сертифик
Q>Т.е. тут: Тоже сделал, все ок. Вводите имя, страна RU, ставим флажок "Пометить ключ как экспортируемый" остальные поля без изменений и нажимаем выдать.
тоже самое поставил RU и даже попробавл с разными версиями дотнета. может нужна лицензия на клиента?
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[13]: Как определить доступность закрытого ключа к сертифик
Здравствуйте, vaa, Вы писали:
vaa>Здравствуйте, Qulac, Вы писали:
Q>>Т.е. тут: Тоже сделал, все ок. Вводите имя, страна RU, ставим флажок "Пометить ключ как экспортируемый" остальные поля без изменений и нажимаем выдать.
vaa>тоже самое поставил RU и даже попробавл с разными версиями дотнета. может нужна лицензия на клиента?
Если с лицензиями не так, она обычно диалог выводит при вызове, а так в начале идет триал. Лицензии можно посмотреть Пуск — Управление лицензиями КриптоПро PKI.
Программа – это мысли спрессованные в код
Re[14]: Как определить доступность закрытого ключа к сертифик
vaa>>тоже самое поставил RU и даже попробавл с разными версиями дотнета. может нужна лицензия на клиента?
Q>Если с лицензиями не так, она обычно диалог выводит при вызове, а так в начале идет триал. Лицензии можно посмотреть Пуск — Управление лицензиями КриптоПро PKI.
истек