27.06.2006 23:16:15Определение необходимости задания PIN-сода Ответов: 7
Роман Харитонов
При получении сертификатов хранимых в контейнерах, находящихся на eToken-е натолкнулся на особенность работы с контейнерами:
Контейнеры созданные с помощью CSP 2.0 при вызове CPGetUserKey() выводят UI c запросом PIN-кода
Контейнеры созданные с помощью CSP 3.0 подобных запросов не выводят.

Подскажите, пожалуйста, существует ли программный способ определения нужно ли вызывать
CPSetProvParam(hProv,PP_SIGNATURE_PIN,pPIN,0)
перед
CPGetUserKey(hProv,AT_SIGNATURE,phUserKey)
Чтобы UI c запросом PIN-кода не выводился.

Заранее спасибо.

 
Ответы:
28.06.2006 15:48:01Василий
Вообще-то CSP, на котором делали контейнер, не должен иметь значения. Влияет версия CSP, на котором открывается контейнер. Для 3.0 больше операций не требуют ПИНа.

Для того, чтобы не было UI - используйте флажок CRYPT_SILENT и FQCN-имя контейнера в ф-и ..AcquireContext.

Тогда, при соответствующей ошибке функции работы с ключами (0x8010006B) можно понять, нужно ли задавать ПИН - и задать его программно или переоткрыть контейнер и спросить ПИН у пользователя.
28.06.2006 23:37:55Роман Харитонов
К сожалению описанный Вами способ не сработал
под CryptoPro 3.0 для контейнера созданного CSP 2.0 при вызове функции CPGetUserKey(...) без задания PIN-кода, возвращается FALSE, а код ошибки, получаемый функцией GetLastError() всегда 0x8009000D (NTE_NO_KEY), в независимости есть ключ или нет.
Хочется узнать есть ли какой-нибудь программный способ определить какой версией CSP был создан контейнер ?
29.06.2006 10:44:57Василий
Можно уточнить - это при открытии контекста с флажком CRYPT_SILENT ? А без него - работает?
29.06.2006 12:13:51Роман Харитонов
Да, ошибка возникает при открытии контекста с флагом CRYPT_SILENT. Если этот флаг не указывать то при вызове
CPGetUserKey(...) поднимается UI c запросом PIN-кода - если PIN-код ввести правильно все проходит хорошо, если PIN-код неверный возвращается ошибка 0x8009000D (NTE_NO_KEY).
Есть ли способ определить какой версией CSP был создан контейнер ?
29.06.2006 16:26:50Василий
Отличие контейнеров, созданных версией CSP 3 от 2 в том, что файл \e00e\0b00\CCxx\f003 (аналог "header.key") в случае 3-й версии не требует ПИН (Public binary file). Именно в нём хранится сертификат (если он есть в контейнере). Собственно, так и было задумано.

Может, Вам поступить проще - всегда сначала задавать ПИН программно, а если операция требует ПИНа и обломается из-за того, что ПИН неверный - то спросить его через UI.

29.06.2006 19:37:38Роман Харитонов
Спасибо, за информацию о расположении данных в контейнере,
действительно все так, как Вы написали.

Но предлагаемый способ так же не сработал.
под CryptoPro 3.0 для контейнера созданного CSP 2.0 при вызове функции CPGetUserKey(...) с установленным неверным PIN-кодом, возвращается FALSE, а код ошибки, получаемый функцией GetLastError() всегда 0x8009000D (NTE_NO_KEY), в независимости есть ключ или нет.

Если нет возможности узнать, кем был создан контейнер
придется без установки PIN-кода вызывать подряд
CPGetUserKey(..AT_SIGNATURE..)
CPGetUserKey(.AT_KEYEXCHANGE..)
и если оба вызова не увенчаются успехом спрашивать у пользователя
PIN-код, выставлять его и повторять попытку получения ключа еще раз.
Хочется понять будет ли выполнять CryptoPro логин на токен, когда вызывается CPGetUserKey(...) без установленного PIN-кода ? Так как количество веденных неверно PIN-кодов на eToken-ах обычно ограничивается.
30.06.2006 15:34:22Василий
Чтобы совсем всё было правильно, конечно, нужен конвертер ключевых контейнеров на токене, который бы снимал требование ПИН-кода при доступе к этому файлу. Поскольку именно на этом уровне самим токеном определяется, что ПИН нужен. А поскольку CSP 3 считает, что в этом случае (GetUserKey) ПИН не должен спрашиваться, то он и не кмеет выставить правильную ошибку, и говорит, что ключа нет совсем.
Так что, придётся спрашивать ПИН у пользователя для контейнеров, сделанных на 2.0.