16.05.2005 17:22:12Помещаем с помощью КриптоПро контейнер секретного ключа на RuToken. Ответов: 9
Евгений
Каким образом потом можно извлечь этот контейнер с токена, какие функции использовать? При условии, что есть возможность считать любой файл.
Что было проделано - проверка на PFX не срабатывает. Просто как чтение сертификата из файла - тоже.

Хочется, чтобы можно было подписывать с помощью сертификата в контейнере, чтобы можно было просматривать его свойства.
 
Ответы:
17.05.2005 14:47:00Василий
Смотря какая схема использования ключа и сертификата:
1) Сертификат установлен в хранилище сертификатов Windows с привязкой к контейнеру секретного ключа. В этом случае можно использовать готовые приложения (например, Приложение командной строки, КриптоАРМ, MS Outlook,...) или вызовы из Вашего приложения высокоуровневых функций работы с сертификатами для ЭЦП и шифрования (CAPICOM или Simplified Message Functions или Low-level Message Functions). Они сами, когда будет нужно, вызовут функции CSP для доступа к ключу в контейнере.
2) Вы используете более низкоуровневые функции CryptoAPI для работы с контейнером, т.е. самостоятельно вызываете ф-ю открытия контекста (CryptAcquireContext), затем ф-ю чтения ключа (CryptGetUserKey), затем ф-ю чтения сертификата из контейнера(CryptGetKeyParam) и т.д.
18.05.2005 17:06:48Евгений
Сертификат не установлен в локальных хранилищах, поэтому использую способ два. Но возникли проблемы. Вызываю CryptAcquireContext так:
CryptAcquireContext(
&hProv,
NULL,
"Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider",
75,
NULL), намереваясь получить дескриптор провайдера, чтобы дальше воспользоваться CryptGetProvParam с параметром PP_ENUMCONTAINERS, после чего имея имена контейнеров, вызывать опять CryptAcquireContext с именем контейнера, потом CryptGetUserKey и CryptGetKeyParam - как Вы и сказали (я же правильно мысль уловил?). После первого вызова CryptAcquireContext всплывает UI криптопровайдера, где показан список носителей, причем при выборе токена, говорит, что набор ключей не существует (оно и понятно, т.к. я NULL в имени контейнера передаю). Но чтобы мне получить имена контейнеров, мне надо заставить работать CryptAcquireContext. Замкнутый круг. Как его можно разорвать?
18.05.2005 17:59:21Василий
Ну разумеется.
Если не хотите, чтобы спрашивали носитель - используйте флаг CRYPT_VERIFYCONTEXT в первом вызове CryptAcquireContext
20.05.2005 10:57:17Евгений
Да спасибо, так работет, но снова возникли вопросы - после второго вызова CryptAcquireContext возникает на некоторое время UI с носителями и автоматом потом исчезает (вызов с ключом NULL, с CRYPT_SILENT возращается ошибка) - можно поборть возникновение этого окошка?
И второй вопрос - как однозначно определить, что этот контейнер принадлежит не реестру, а какому-либо носителю?
20.05.2005 12:36:46maxdm
Вам поможет вызов PP_ENUMCONTAINERS c флагом CRYPT_FQCN = 0x10 (Fully Qualified Container Name) - решится и первая и вторая проблема
20.05.2005 12:49:43Евгений
Какой-то недокументированный ключ, но он помог со второй проблемой.

Первая же проблема остается (после передачи полного имени конейнера, т.е. с SCARD\etc). Как я говорил, я пытался использовать ключ CRYPT_SILENT, но в МСДН есть такая ремарка:
The application requests that the CSP not display any user interface (UI) for this context. If the CSP must display the UI to operate, the call fails and the NTE_SILENT_CONTEXT error code is set as the last error.

Может, ваш CSP не может не отображать это окно?
20.05.2005 14:00:51maxdm
А без CRYPT_SILENT какое окно отображается? Случайно не ввода пина?
23.05.2005 1:24:30Евгений
Контекст просто не инициализируется с этим ключем.
Кстати, я посмотрел - если с помощью средств самого провайдера смотреть сертификаты в контейнере - окошко тоже всплывает. Т.е. сервис-просмотреть сертификаты в контейнере и дальше. Окошко появляется.

И еще вопрос - я получаю pCertContext, могу с его помощью шифровать, но подписывать не могу, т.к. не может найти закрытый ключ (функция CertGetCertificateContextProperty). Надо использовать функции более низкого уровня для подписывания?

Но как же тогда быть с операцией подписывание/шифрование?
23.05.2005 1:43:02Я
Насчет подписания разобрался, да, использовать функции более низного уровня. Подписание/шифрование работает нормально... А вот насчет проверки еще не знаю, т.к. какое ей подсовывать хранилище? Я насчет функции CryptDecryptAndVerifyMessageSignature.