Статус: Новичок
Группы: Участники
Зарегистрирован: 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)
| Причина: Не указана
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 12,630 Сказал «Спасибо»: 494 раз Поблагодарили: 2035 раз в 1579 постах
|
Здравствуйте.
Варианты: 1) через хранилище - получать полную информацию о контейнере, на который ссылается сертификат. Требования: сертификат должен быть установлен в хранилище и иметь ссылку на контейнер 2) через работу с контейнерами - извлекать из него сертификат. Требования: сертификат должен быть в контейнере, в логике программы - привязка к конткретному типу носителя (исключить: реестр\флешки\рутокены...)
В чем сложность хранить отпечаток\информацию о сертификате в контексте текущего пользователя (для этого и существует Профиль пользователя, как и хранилище My), а не записывать в ini там, где находится программа, тем самым порождая новые проблемы с многопользовательской работой с сетевого диска.
В appdata почему не храните сведения? |
|
1 пользователь поблагодарил Андрей * за этот пост.
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 12,630 Сказал «Спасибо»: 494 раз Поблагодарили: 2035 раз в 1579 постах
|
Цитата:либо делать выбор нужного через диалог CryptUIDlgSelectCertificateFromStore, что приводит к лишним ошибкам со стороны пользователя. Третий вариант - свой диалог, со своими фильтрами (например, показывать только ГОСТ CSP, только в реесте\рутокене\HDD)
GUI.png (73kb) загружен 11 раз(а).
Насчет получения сертификата из контейнера: CryptGetKeyParam (hSenderKey, KP_CERTIFICATE, вызывается дважды - первый раз для получения размера, второй раз - для записи сертификата в переменную (pbCertificate). Далее контекст получаем : pCertContext = CertCreateCertificateContext( X509_ASN_ENCODING, pbCertificate, .. + можно в файл записать для показа в ОС или передать в CryptUIDlgViewCertificate (в контексте своего ПО отобразить). |
|
1 пользователь поблагодарил Андрей * за этот пост.
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 12,630 Сказал «Спасибо»: 494 раз Поблагодарили: 2035 раз в 1579 постах
|
Цитата:Сертификат берется из носителя или из того же личного хранилища? Если - CryptGetKeyParam (hSenderKey, KP_CERTIFICATE - то это из контейнера и он может быть не установлен в хранилище My. |
|
1 пользователь поблагодарил Андрей * за этот пост.
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 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)
| Причина: Не указана
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 12,630 Сказал «Спасибо»: 494 раз Поблагодарили: 2035 раз в 1579 постах
|
Самое главное - результат функций проверять, а то CryptGetKeyParam может и false вернуть. |
|
1 пользователь поблагодарил Андрей * за этот пост.
|
|
|
Статус: Новичок
Группы: Участники
Зарегистрирован: 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)
| Причина: Не указана
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close