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

Уведомление

Icon
Error

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

Статус: Участник

Группы: Участники
Зарегистрирован: 13.01.2011(UTC)
Сообщений: 16

В нашей системе не используется установка сертификатов в хранилище в Windows (требования заказчика).
Выбор сертификата для криптографических операций происходит по следующей схеме:
получения списка контейнеров через CryptGetProvParam с PP_ENUMCONTAINERS,
получением HCRYPTKEY через CryptGetUserKey с AT_SIGNATURE или AT_KEYEXCHANGE,
далее через CryptGetKeyParam с KP_CERTIFICATE получаем сертификат.

С шифрованием, подписью(здесь используем CertSetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, 0, &provInfo))
и проверкой подписи все хорошо, но что делать с расшифровкой?
Функция CryptDecryptMessage требует список хранилищ сертификатов, откуда его взять?
Offline Максим Коллегин  
#2 Оставлено : 30 мая 2011 г. 20:45:15(UTC)
Максим Коллегин

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

Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC)
Сообщений: 6,396
Мужчина
Откуда: КРИПТО-ПРО

Сказал «Спасибо»: 37 раз
Поблагодарили: 719 раз в 623 постах
Создайте хранилище в памяти, содержащее сертификат для расшифрования и передайте его.
Знания в базе знаний, поддержка в техподдержке
Offline altazar  
#3 Оставлено : 30 мая 2011 г. 20:51:03(UTC)
altazar

Статус: Участник

Группы: Участники
Зарегистрирован: 13.01.2011(UTC)
Сообщений: 16

Но для того чтобы получить сертификат, мне придется "обзванивать" все контейнеры(их может быть подключено несколько), собирать сертификаты и складывать в хранилище, на каждом этапе такой сборки вводить пин коды (требование заказчика не запоминать их в памяти CSP), а это снижает удобство системы, есть ли еще какие-то варианты?
Offline Максим Коллегин  
#4 Оставлено : 30 мая 2011 г. 20:52:11(UTC)
Максим Коллегин

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

Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC)
Сообщений: 6,396
Мужчина
Откуда: КРИПТО-ПРО

Сказал «Спасибо»: 37 раз
Поблагодарили: 719 раз в 623 постах
Если сертификат есть в контейнере - пин-код не спросится (для 3.6).
Знания в базе знаний, поддержка в техподдержке
Offline altazar  
#5 Оставлено : 30 мая 2011 г. 21:05:17(UTC)
altazar

Статус: Участник

Группы: Участники
Зарегистрирован: 13.01.2011(UTC)
Сообщений: 16

Спасибо за Ваши ответы, буду использовать как рабочий вариант решения.
Offline altazar  
#6 Оставлено : 1 июня 2011 г. 16:13:41(UTC)
altazar

Статус: Участник

Группы: Участники
Зарегистрирован: 13.01.2011(UTC)
Сообщений: 16

Возможная ошибка в CSP.
В продолжение темы:
1) Есть 4 контейнера в реестре и 4 их копии на токене (пока без сертификатов в контейнерах) все контейры(8) имееют разные имена

2) в контейнеры в реесте скопированы сертификаты с помощью
csptest -property -setcert -provtype CProCSP -container "petrov_new_reestr" -cert "petrov" -store user -storename my

3) далее произведена таже операция (копирование тех же 4х сертификатов) с контейнерами на токене,
4) сертификаты удалены из хранилища MY.

5) Токен удален из системы

Далее программа производит следующие действия:

CryptAcquireContext(
&hCryptProv,
NULL,
NULL,
providerID,
CRYPT_VERIFYCONTEXT);

HANDLE hStore = CertOpenStore(
CERT_STORE_PROV_MEMORY,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
hCryptProv,
0,
NULL);

Перебираем контейнеры(причем получаем естественно только список контейнеров в реестре)

BOOL res = CryptGetProvParam(hCryptProv, PP_ENUMCONTAINERS, pContainerName, &containerNameSize, CRYPT_FIRST);
while(res)
{
Получаем сертификат в контейнере

HCRYPTKEY hKey = NULL;
CryptGetUserKey(hCP, AT_SIGNATURE, &hKey);
if(hKey==NULL)
CryptGetUserKey(hCP, AT_KEYEXCHANGE, &hKey);
...
CryptGetKeyParam(.., KP_CERTIFICATE, ...)
...
Создаем контекст сертификата
...
Связывает с закрытым ключом
...
CRYPT_KEY_PROV_INFO provInfo;
ZeroMemory(&provInfo, sizeof(CRYPT_KEY_PROV_INFO));
provInfo.dwProvType = 75;
provInfo.pwszContainerName = containerName;
provInfo.pwszProvName=L"Crypto-Pro GOST R 34.10-94 Cryptographic Service Provider";

CertSetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, 0, &provInfo);
...
Добавляем сертификат в хранилище в памяти
CertAddCertificateContextToStore(hStore, pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL)

res = CryptGetProvParam(hCryptProv, PP_ENUMCONTAINERS, pContainerName, &containerNameSize, CRYPT_NEXT);
}

Далее при попытке вызова
CryptDecryptMessage

Появляется окно CSP c просьбой вставить токен....что странно


Offline Максим Коллегин  
#7 Оставлено : 1 июня 2011 г. 17:17:25(UTC)
Максим Коллегин

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

Группы: Администраторы
Зарегистрирован: 12.12.2007(UTC)
Сообщений: 6,396
Мужчина
Откуда: КРИПТО-ПРО

Сказал «Спасибо»: 37 раз
Поблагодарили: 719 раз в 623 постах
Вместе с удалением сертификатов нужно удалять еще KeyIdentifiers.
Код:
    //попробуем удалить существующий KeyID - при установке сертификата создастся новый 
    DWORD dwLen = 0;
    if ( CertGetCertificateContextProperty(ctx, CERT_KEY_IDENTIFIER_PROP_ID, NULL, &dwLen) )
    {
	BYTE *pbData = new BYTE[dwLen];
	if ( CertGetCertificateContextProperty(ctx, CERT_KEY_IDENTIFIER_PROP_ID, pbData, &dwLen) )
	{
	    CRYPT_HASH_BLOB blob = { dwLen, pbData };
	    CryptSetKeyIdentifierProperty(&blob, 0, CRYPT_KEYID_DELETE_FLAG, NULL, NULL, NULL);
	}
	delete[] pbData;
    }

Отредактировано пользователем 1 июня 2011 г. 17:18:25(UTC)  | Причина: Не указана

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