Closed AshurkovAV closed 4 years ago
Здравствуйте. Такого функционала нет. Что именно вы пытаетесь сделать?
Просмотреть ключи на носителе Rutoken. Например как .net КриптоПро Gost3410CryptoServiceProvider.SelectContainer(true, false, IntPtr.Zero). Это выдаст диалоговое окно именно криптопро-шное.
На счет диалогового окна не уверен, а вот функцию, которая будет возвщать список, можно будет попробовать реализовать. Это будет полезно?
Да очень нужно, это будет полезно
Хорошо. Постараюсь помочь. :)
Спасибо, примерно по времени, когда можно ждать.
Постараюсь в начале следующей нели предоставить тестовый образец.
Спасибо!!!
@AshurkovAV Можете проверить на последнем коммите, возвращает ли следующий код то, что вам нужно:
var containers = CryptoApiHelper.GetContainers(ProviderType.VipNet_2012_1024,
fullContainerName: true, storeLocation: StoreLocation.LocalMachine);
Если все ОК, я выпущу новую версию пакета.
Да все сработало, вернулся список имен контейнеров. Спасибо! А как получить сертификат из контейнера! Куда благодарность направить? Хочу поддержать проект. :)
Да все сработало
Отлично. :)
А как получить сертификат из контейнера
Первое, что приходит в голову - это сделать прямой перебор. Например, так:
public static X509Certificate2 FindCertificateByContainerName(
string containerName,
StoreName storeName = StoreName.My,
StoreLocation storeLocation = StoreLocation.LocalMachine)
{
var store = new X509Store(storeName, storeLocation);
store.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadOnly);
try
{
foreach (var certificate in store.Certificates)
{
if (certificate.HasPrivateKey
&& certificate.IsGost()
&& certificate.GetPrivateKeyInfo().KeyContainerName == containerName)
{
return certificate;
}
}
}
finally
{
store.Close();
}
return null;
}
Куда благодарность направить? Хочу поддержать проект. :)
Ставьте звездочку :)
Александр, еще вопрос. Необходимо найти способ получения сертификата со смарт карты (USB токена) и подписывания некоторых данных приватным ключом с этого токена. Возможно ли такое
Думаю, что возможно. :) Я правильно понимаю, что реализованная выше функция перечисления позволяет найти и выбрать контейнер. (Этот контейнер в нашем случае находится на внешнем носителе - USB токен.) Далее, имея имя контейнера, вы хотите получить сертификат с закрытым ключом для подписи. И, я полагаю, его нет в X509Store и его нельзя получить/найти, как я предложил выше. Все так? :)
Прям в точку. Верно!
если их несколько буду предлагать пользователю выбрать один
Полагаю, что для создания подписи вам не нужен именно X509Certificate
. Можно попробовать создать подходящий ассиметричный алгоритм, используя конструктор, который принимает CspParameters
. Например:
var keyContainer = new CspParameters
{
ProviderType = (int) ProviderType.VipNet_2012_512,
Flags = CspProviderFlags.UseMachineKeyStore,
KeyNumber = (int) KeyNumber.Signature,
KeyContainerName = @"path/to/key/container"
};
var signingKey = new Gost_R3410_2012_256_AsymmetricAlgorithm(keyContainer);
Обратите внимание, что ProviderType
должен соответствовать ключу; Flags
- зависит от того, где находится контейнер (хранилище машины или учетной записи пользователя); KeyContainerName
- полный путь к ключу, полученный вышеуказанным методом.
Далее создаем экземпляр ассиметричного алгоритма с нужным типом, который также должен соответствовать ключу. Значение signingKey
можно использовать для создания подписи.
Думаю, что у вас получится сделать метод получения signingKey
из контейнера более универсальным, чем приведенный код. :) Есть небольшой пример, как подписывать XML документ, используя информацию о контейнере. (Правда, в целях универсальности теста экземпляр CspParameters
создается не в ручную, а извлекается из сертификата.)
Если все ОК, дайте знать. :)
Доброе утро, спасибо! Подписать документ у меня получилось, но проблема еще состоит в том, что я должен передать в блоке BinarySecurityToken сведение о сертификате, с помощью которого была рассчитана ЭП. После чего я весь документ еще должен зашифровать. Шифрование до этого делал через сертификат. :)!!!!!
Спасибо за детали. Постараюсь сделать это к концу текущей недели.
Спасибо! Жду!
Александр, добрый день. Извини за назойливость, подскажи получилось реализовать данный функционал?
Нужный функционал реализовал в последней правке, проверьте, пожалуйста. Суть использования такова. Создаем приватный ключ на основе данных о контейнере, как описано выше. Далее на основе него получаем сертификат.
Например, так можно получить сертификат, который не включает приватный ключ:
X509Certificate2 certificate = signingKey.GetCertificate();
Так - сертификат, который использует signingKey
, как приватный ключ:
X509Certificate2 certificate = signingKey.GetCertificate(true);
Жду обратной связи. :)
Да, все получилось, мне вернулся сертификат. Спасибо!!! Ваш проект очень полезный :)
Спасибо, поставил!
Александр, добрый день. А это же алгоритм должен сработать для криптопровайдер КриптоПро (CryptoPro_2012_256) Как это реализовать. У меня возвращается Null
Да, все должно работать и для CryptoPro, к сожалению не могу сейчас проверить - нет подходящего окружения. Метод GetCertificate()
возвращает null в случае, если криптопровайдер вернул ошибку ERROR_NO_SUCH_CERTIFICATE
для заданной ключевой пары. Вообще это мало о чем говорит. :) Тем не менее, может быть сертификат доступен под другой учетной записью? А у текущей нет прав доступа.
Здравствуйте, как просмотреть ключи в контейнере , используя GostCryptography. Криптопровайдер VipNet