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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline clipper  
#1 Оставлено : 30 сентября 2018 г. 8:45:10(UTC)
clipper

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

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

Сказал(а) «Спасибо»: 9 раз
Создаю отсоединенную цифровую подписи через сертификат открытого ключа с помощью CryptSignMessage. При заполнении структуры pSignPara указываю ссылку на сертификат открытого ключа, найденный в хранилище через CertFindCertificateInStore. При этом в личном хранилище "MY" находятся сертификаты других криптопровайдеров и приходится имя нужного сертификата хранить либо в ini файле (это не удобно, так как программу запускают несколько пользователей с одного сетевого ресурса), либо делать выбор нужного через диалог CryptUIDlgSelectCertificateFromStore, что приводит к лишним ошибкам со стороны пользователя.
При этом в самом ключевом носителе находится внедренный (причем единственный) сертификат, который можно было бы использовать при заполнении pSignPara.
Подскажите как можно получить на него ссылку? Пытался через вызов CryptGetKeyParam (hSenderKey, KP_CERTIFICATE, pbUserCert, dwUserCertLength, 0 ) но не совсем понял что делать дальше. Сертификат берется из носителя или из того же личного хранилища?

Отредактировано пользователем 30 сентября 2018 г. 9:07:47(UTC)  | Причина: Не указана

Offline Андрей Писарев  
#2 Оставлено : 30 сентября 2018 г. 11:40:58(UTC)
Андрей *

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

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

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

Варианты:
1) через хранилище - получать полную информацию о контейнере, на который ссылается сертификат.
Требования: сертификат должен быть установлен в хранилище и иметь ссылку на контейнер
2) через работу с контейнерами - извлекать из него сертификат.
Требования: сертификат должен быть в контейнере, в логике программы - привязка к конткретному типу носителя (исключить: реестр\флешки\рутокены...)


В чем сложность хранить отпечаток\информацию о сертификате в контексте текущего пользователя (для этого и существует Профиль пользователя, как и хранилище My), а не записывать в ini там, где находится программа, тем самым порождая новые проблемы с многопользовательской работой с сетевого диска.

В appdata почему не храните сведения?
Техническую поддержку оказываем тут
Наша база знаний
thanks 1 пользователь поблагодарил Андрей * за этот пост.
clipper оставлено 30.09.2018(UTC)
Offline Андрей Писарев  
#3 Отправлено: : 30 сентября 2018 г. 11:48:45(UTC)
Андрей *

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

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

Сказал «Спасибо»: 494 раз
Поблагодарили: 2035 раз в 1579 постах
Цитата:
либо делать выбор нужного через диалог CryptUIDlgSelectCertificateFromStore, что приводит к лишним ошибкам со стороны пользователя.


Третий вариант - свой диалог, со своими фильтрами (например, показывать только ГОСТ CSP, только в реесте\рутокене\HDD)


Насчет получения сертификата из контейнера:
CryptGetKeyParam (hSenderKey, KP_CERTIFICATE,
вызывается дважды - первый раз для получения размера, второй раз - для записи сертификата в переменную (pbCertificate).

Далее контекст получаем :

pCertContext = CertCreateCertificateContext( X509_ASN_ENCODING, pbCertificate, ..
+ можно в файл записать для показа в ОС или передать в CryptUIDlgViewCertificate (в контексте своего ПО отобразить).
Техническую поддержку оказываем тут
Наша база знаний
thanks 1 пользователь поблагодарил Андрей * за этот пост.
clipper оставлено 30.09.2018(UTC)
Offline Андрей Писарев  
#4 Оставлено : 30 сентября 2018 г. 11:50:30(UTC)
Андрей *

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

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

Сказал «Спасибо»: 494 раз
Поблагодарили: 2035 раз в 1579 постах
Цитата:
Сертификат берется из носителя или из того же личного хранилища?


Если - CryptGetKeyParam (hSenderKey, KP_CERTIFICATE - то это из контейнера и он может быть не установлен в хранилище My.

Техническую поддержку оказываем тут
Наша база знаний
thanks 1 пользователь поблагодарил Андрей * за этот пост.
clipper оставлено 30.09.2018(UTC)
Offline clipper  
#5 Оставлено : 30 сентября 2018 г. 13:09:35(UTC)
clipper

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

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

Сказал(а) «Спасибо»: 9 раз
Автор: Андрей Писарев Перейти к цитате
Здравствуйте.
В чем сложность хранить отпечаток\информацию о сертификате в контексте текущего пользователя (для этого и существует Профиль пользователя, как и хранилище My), а не записывать в ini там, где находится программа, тем самым порождая новые проблемы с многопользовательской работой с сетевого диска.
В appdata почему не храните сведения?

Здравствуйте Андрей.
Нужно более гибкое решение, например ПК может залогинен не под учетной записью пользователя, а под единой технологической, ключевые устройства у пользователей индивидуальные.
Плюс при замене пользователя на удаленном ПК необходимо дополнительно вносить настройки в профиль, что бы подпись заработала. При использовании сертификата в контейнере, достаточно просто заменить ключевой носитель. Его внедрение непосредственно в контейнер, кроме хранилища не трудоемкое.

Автор: Андрей Писарев Перейти к цитате
Насчет получения сертификата из контейнера:
CryptGetKeyParam (hSenderKey, KP_CERTIFICATE,
вызывается дважды - первый раз для получения размера, второй раз - для записи сертификата в переменную (pbCertificate).

Вызывал дважды
Код:

CryptGetKeyParam  (hSenderKey, KP_CERTIFICATE, nil, dwUserCertLength, 0)
GetMem(pbUserCert, dwUserCertLength);
CryptGetKeyParam  (hSenderKey, KP_CERTIFICATE, pbUserCert, dwUserCertLength, 0)

Автор: Андрей Писарев Перейти к цитате
Далее контекст получаем :
pCertContext = CertCreateCertificateContext( X509_ASN_ENCODING, pbCertificate, ..
+ можно в файл записать для показа в ОС или передать в CryptUIDlgViewCertificate (в контексте своего ПО отобразить).

Андрей, спасибо CertCreateCertificateContext как раз то, что нужно. Все заработало. Полученный через контекст сертификат из контейнера вставил в структуру pSignPara.

Автор: Андрей Писарев Перейти к цитате
Если - CryptGetKeyParam (hSenderKey, KP_CERTIFICATE - то это из контейнера и он может быть не установлен в хранилище My.

Да действительно. Проверил убрав сертификат из MY.

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

Offline Андрей Писарев  
#6 Оставлено : 30 сентября 2018 г. 13:14:23(UTC)
Андрей *

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

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

Сказал «Спасибо»: 494 раз
Поблагодарили: 2035 раз в 1579 постах
Самое главное - результат функций проверять, а то CryptGetKeyParam может и false вернуть.
Техническую поддержку оказываем тут
Наша база знаний
thanks 1 пользователь поблагодарил Андрей * за этот пост.
clipper оставлено 30.09.2018(UTC)
Offline clipper  
#7 Оставлено : 30 сентября 2018 г. 13:43:16(UTC)
clipper

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

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

Сказал(а) «Спасибо»: 9 раз
Автор: Андрей Писарев Перейти к цитате
Самое главное - результат функций проверять, а то CryptGetKeyParam может и false вернуть.

Ключи с сертификатами для клиентов генерирую сам, за годы работы рефлекс все перепроверять на несколько раз выработался, но лишняя проверка не помешает.
Код:
if not CryptGetKeyParam  (hSenderKey, KP_CERTIFICATE, nil, dwUserCertLength, 0) then
begin
  Memo1.Lines.Add('Ошибка получения параметров сертификата в контейнере: ' +
  SysErrorMessage(GetLastError) + ' - ' +IntToStr(GetLastError));
  Exit;
end;

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

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