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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline kaper_75  
#1 Оставлено : 12 сентября 2018 г. 13:12:26(UTC)
kaper_75

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

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

Сказал(а) «Спасибо»: 2 раз
Добрый день. Установлена сертифицированная версия 4.0.9944.

Вызов функция КриптоПро из в Delphi

Функция CryptSetProvParam(hProv, PP_KEYEXCHANGE_PIN, 0, 0) - всегда возвращает True. Окно ввода ПМН НЕ ВЫВОДИТСЯ. Как результат при попытке формирования ХЭШ - ошибка "Плохой ключ"

Если установить версию 4.0.9330 или 3.9 все отрабатывает корректно.
Вопрос что-то менялось в 4 версии или вызов функции сменился?
Спасибо
Offline Агафьин Сергей  
#2 Оставлено : 12 сентября 2018 г. 13:39:18(UTC)
Grey

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

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

Сказал «Спасибо»: 5 раз
Поблагодарили: 215 раз в 174 постах
Добрый день. Вызов PP_KEYEXCHANGE_PIN с нулем не предназначен для вывода окна аутентификации - он сбрасывает текущий пароль.

Если вы хотите гарантированно прогрузить ключи в память с аутентификацией, если она требуется, используйте CryptGetProvParam(PP_HCRYPTPROV) - это рекомендуемый путь.

Если вам нужно именно окно аутентификации вне зависимости от того, нужен провайдеру пароль или нет, нужно позвать CryptSetProvParam(PP_SET_PIN): он принимает аргументом указатель на структуру типа CRYPT_PIN_PARAM. Вам нужно в её поле установит значение CRYPT_PIN_QUERY.
С уважением,
Сергей
Техническую поддержку оказываем здесь.
Наша база знаний.
Offline kaper_75  
#3 Оставлено : 12 сентября 2018 г. 14:37:01(UTC)
kaper_75

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

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

Сказал(а) «Спасибо»: 2 раз
Я что-то запутался. Может что-то не то делаю. Мне необходимо сформировать ХЭШ и подписать его

Упуская блоки выделения/освобождения памяти. У меня примерно так формируется

Выбираем сертификат
hStoreHandle := CertOpenSystemStore(0, 'MY');
pCertContext := CryptUIDlgSelectCertificateFromStore(hStoreHandle, 0, '', '', 0, 0, nil);

получение информации о ключе
CertGetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID,KeyProvInf,@DataSize);

my_cont:=KeyProvInf.pwszContainerName;
my_prov:=KeyProvInf.pwszProvName;

подключаемся к криптопровайдеру с нужным контейнером
CryptAcquireContext(@hProv,pansichar(AnsiString(my_cont)),pansichar(AnsiString(my_prov)),PROV_RSA_FULL,0)

CryptGetUserKey(hProv,AT_KEYEXCHANGE,@PublicKey)

создание ХЭШ-объекта
CryptCreateHash(hProv, alg, PublicKey, 0, @hash) - и вот на данной строке - ПЛОХОЙ КЛЮЧ

формирование ХЭШ
CryptHashData(hash, PByte(s), size, 0)
CryptGetHashParam(hash, HP_HASHVAL, pbHash_, @DataSize, 0)

Подписание ХЭШ
CryptSignHash(hash,AT_KEYEXCHANGE,nil,0,pbHash,@DataSize)

Отредактировано пользователем 12 сентября 2018 г. 14:40:39(UTC)  | Причина: Не указана

Offline two_oceans  
#4 Оставлено : 13 сентября 2018 г. 7:58:34(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 1,602
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 110 раз
Поблагодарили: 397 раз в 367 постах
1. Если уже есть контекст сертификата, то хэндл криптопровайдера с закрытым ключом (hProv) гораздо проще получить через CryptAcquireCertificatePrivateKey чем через CryptAcquireContext, так как: а) dwKeySpec для выбора ключа, соответсвующего именно этому сертификата в контейнере закрытого ключа определится автоматически и запишется в переменную (то место где в CryptGetUserKey жестко прописано AT_KEYEXCHANGE выдаст ошибку, если на самом деле выбранный сертификат соответвует ключу AT_SIGNATURE) и б) не нужно пользоваться константой PROV_RSA_FULL (мягко говоря подозрительной, когда речь о КриптоПро CSP). В формуляре 4.0.4944 функция CryptAcquireCertificatePrivateKey разрешена. Предположительно могут быть странности с определением контейнера по CRYPT_ACQUIRE_COMPARE_KEY_FLAG в редком случае наличия 2 доступных контейнеров с одним и тем же ключом, соответствующим выбранному сертификату и с разными пин-кодами (некоторые УЦ делают "резервную копию" контейнера на том же токене).

2. Конкретная последовательность действий зависит от Вашей задачи - при создании хэша CryptCreateHash параметр ключа hKey необязательный. Как сказано в справке Майкрософт ключ должен быть ненулевой только для алгоритмов, которые требуют ключа шифрования блока (MAC HMAC алгоритмы), а для алгоритмов не требующих ключа параметр устанавливается в 0. Получается ошибка означает либо а) алгоритм не требует ключа (из исходника не видно значения alg, поэтому неизвестно требует ли) либо б) ключ не подходит для alg. Для вычисления хэша/подписи по алгоритму ГОСТ 34.11-94/34.10-2001 (alg хэша=32798=$801E) hKey устанавливается в 0.

3. Для информации: в общем случае для получения хэндла открытого ключа по контексту сертификата даже не нужно запрашивать контейнер закрытого ключа, так как открытый ключ уже указан в сертификате - можно создать CryptAcquireContext с указанием VERIFYCONTEXT и импортировать в него через CryptImportPublicKeyInfo блоб открытого ключа из контекста как @(pCertContext^.pCertInfo^.SubjectPublicKeyInfo). Опять же без обращения к hProv отпадает необходимость в определении AT_KEYEXCHANGE или AT_SIGNATURE. Также может понадобится если нужно зашифровать сообщение открытым ключом получателя, так как отправитель в этом случае не имеет доступа к контейнеру закрытого ключа получателя.

Отредактировано пользователем 13 сентября 2018 г. 8:20:03(UTC)  | Причина: уточнение

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