Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline mafof  
#1 Оставлено : 17 апреля 2021 г. 19:19:29(UTC)
mafof

Статус: Новичок

Группы: Участники
Зарегистрирован: 17.04.2021(UTC)
Сообщений: 2
Российская Федерация
Откуда: Москва

Всем привет, пытаюсь реализовать функционал подписание данных, но наткнулся на проблему где не понимаю как мне взять приватный ключ из сертификата установленного в сертификаты пользователя -> личные сертификаты. Насколько я понимаю для подписание данных мне нужно использовать метод CryptHashData, в 1-ом аргументе которого необходимо получить переменную типа HCRYPTHASH, которую можно получить через метод CryptCreateHash в 3-ем аргументе которого необходимо получить переменную заполненной структурой HCRYPTKEY, который как я понимаю является приватный ключ из сертификата.
На сколько я понимаю что, что бы получить приватный ключ, необходимо получить дескриптор сертификата и потом связать полученный дескриптор сертификата, с дескриптором криптопровайдера через метод CertSetCertificateContextProperty, и потом получить ключ через метод CryptGetUserKey... Но при попытке так сделать, я получаю ошибку NTE_NO_KEY от метода CryptGetUserKey, и не понимаю почему это так происходит...
Вот мой код:
Код:

// Получаю дескриптор криптопровайдера =>

HCRYPTPROV phProv;
if (!CryptAcquireContext(&phProv, NULL, L"Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider", PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
	if (NTE_KEYSET_NOT_DEF == GetLastError())
	{
		printf("provider is not found");
	}
	else {
		std::cout << GetLastError();
	}
	return 1;
}

// Открываю системное хранилище сертификатов =>

HCERTSTORE hStoreHandle;
hStoreHandle = CertOpenSystemStore(phProv, L"MY");
if (hStoreHandle)
{
	printf("The MY store is open. \n");
}
else
{
	printf("Error getting store handle.");
}

// Получаю сертификат из списка сертификатов =>

PCCERT_CONTEXT pRecipientCert = NULL;
DWORD PropId = CERT_KEY_PROV_INFO_PROP_ID;
pRecipientCert = CertFindCertificateInStore(
	hStoreHandle,
	0,
	0,
	CERT_FIND_PROPERTY,
	&PropId,
	pRecipientCert
);

// Пробую получить дескриптор ключа из сертификата =>

HCRYPTKEY phUserKey;
if (CertSetCertificateContextProperty(
		pRecipientCert,
		CERT_SET_KEY_PROV_HANDLE_PROP_ID,
		0,
		&phProv
	)
)
{
	std::cout << "Success CertSetCertificateContextProperty" << std::endl;
}

if (CryptGetUserKey(phProv, AT_KEYEXCHANGE, &phUserKey))
{
	std::cout << "Success CryptGetUserKey" << std::endl;
}
else 
{
	if(NTE_NO_KEY == GetLastError())
		std::cout <<  "[ERROR] The key requested by the dwKeySpec parameter does not exist." << std::endl; // Тут я получаю эту ошибку...
}

// Дальше должен быть код где я использую методы CryptCreateHash, и CryptHashData...


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

P.S. Метод CertFindCertificateInStore точно возвращает нужный сертификат который содержит закрытый ключ для этого сертификата.

P.S. Меня немного смущает что программа не требует того что бы я воткнул в компьютер USB токен, и не ввел пин код...
Offline Андрей *  
#2 Оставлено : 17 апреля 2021 г. 19:27:37(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 10,664
Мужчина
Российская Федерация

Сказал «Спасибо»: 393 раз
Поблагодарили: 1612 раз в 1238 постах
Здравствуйте.

Что мешает посмотреть в SDK\MSDN?

CertSetCertificateContextProperty - не нужен

Цитата:

Меня немного смущает что программа не требует того что бы я воткнул в компьютер USB токен, и не ввел пин код...


Нет необходимости - не вызывается функция для обращения к ЗК.
Техническую поддержку оказываем тут
Наша база знаний
Offline Андрей *  
#3 Оставлено : 17 апреля 2021 г. 19:34:59(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 10,664
Мужчина
Российская Федерация

Сказал «Спасибо»: 393 раз
Поблагодарили: 1612 раз в 1238 постах
И для какой задачи потребовалось вызывать низкоуровневые функции?

Здесь есть пример, цикл только убрать.
Техническую поддержку оказываем тут
Наша база знаний
Offline Андрей *  
#4 Оставлено : 17 апреля 2021 г. 19:36:28(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 10,664
Мужчина
Российская Федерация

Сказал «Спасибо»: 393 раз
Поблагодарили: 1612 раз в 1238 постах
SDK:
\samples\CSP\SigningHash\SigningHash.c

Техническую поддержку оказываем тут
Наша база знаний
Offline Андрей *  
#5 Оставлено : 17 апреля 2021 г. 19:41:33(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 10,664
Мужчина
Российская Федерация

Сказал «Спасибо»: 393 раз
Поблагодарили: 1612 раз в 1238 постах
SDK:
\samples\CSP\SignUtility\SignUtility.c готовый пример утилиты
(CryptSignMessage\CryptVerifyDetachedMessageSignature)
Техническую поддержку оказываем тут
Наша база знаний
Offline mafof  
#6 Оставлено : 17 апреля 2021 г. 19:58:40(UTC)
mafof

Статус: Новичок

Группы: Участники
Зарегистрирован: 17.04.2021(UTC)
Сообщений: 2
Российская Федерация
Откуда: Москва

Автор: Андрей * Перейти к цитате
И для какой задачи потребовалось вызывать низкоуровневые функции?

Здесь есть пример, цикл только убрать.


Спасибо, буду пытаться вникать дальше, а нужно для создание пакета на Node.js в внутренний продукт.

RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.