07.02.2005 16:24:03Диалог для ПИН и хранение закрытого ключа Ответов: 6
Михаил Копачев
Здраствуйте.
Возникла следующая проблема: при использовании CryptoPro для подписывания нескольких документов потребовалось, чтобы ПИН запрашивался только один раз - в начале. Проблему решил - использовал код как в примере.
Но вот незадача, если после того, как подписалась одна партия документов оказалось возможным вынуть ключевой носитель, при это система продолжает подписывать, не замечая отсутсвия ключевого носителя. В чем дело? Такое поведение было бы логичным, в случае, если бы ключевой носитель оставался, но он вынут.
Как побороть данное поведение?

З.Ы. Ключи не хранятся в службе хранения ключей.
 
Ответы:
08.02.2005 10:08:51Василий
Если ключи не "в службе хранения ключей", то носитель (и пин) спрашивается при первом чтении ключа из контейнера (CryptAcquireContext, CryptGetUserKey). Далее, пока контекст контейнера открыт (не было вызова CryptReleaseContext) ни носитель, ни пин не требуются, т.к. контейнер находится в памяти приложения.
08.02.2005 10:30:35Михаил Копачев
Вы не поняли. Для подписывания используются функции уровня Simplified Message (а конкретно CryptSignMessage()) функции. Они САМИ делают CryptAcquireContext() и прочее. Если не использовать для этого специальных мер, то при 20 вызовах CryptSignMessage() ПИН будет запрошен тоже 20 раз! Эту проблему можно решить установив специальный признак у сертификата:
CertSetCertificateContextProperty(..., CERT_KEY_PROV_INFO_PROP_ID, CERT_STORE_NO_CRYPT_RELEASE_FLAG, ...) и так далее. Полсе такого вызова ПИН запрашивается один раз, НО если, допустим, после подписания 10 документов выдернуть ключевой носитель система этого не заметит (!) и будет продолжать подписывать.
Вопрос: как сделать так, чтобы после изъятия ключевого носителя процесс подписывания останавливался?
08.02.2005 12:23:23Василий
Почему, я суть дела понял. Просто описал на более низком уровне. Здесь явно используется аналог кеширования контейнеров (как в нашей службе хранения ключей) - ключ из контейнера считывается один раз, последующие обращения к нему не требуют ни носителя, ни пина. И так будет до тех пор, пока выставлен этот флажок:
"If CERT_STORE_NO_CRYPT_RELEASE_FLAG is not set, the hCryptProv value is implicitly released either when the property is set to NULL or on the final freeing of the CERT_CONTEXT structure"
08.02.2005 12:43:19Михаил Копачев
Извините, но в любом случае это не ответ. Те сведения, которые Вы приводите я читал, и о них не спрашивал. Я спрашивал как заставить программу не считывать каждый раз контейнер, а проверять наличие ключевого носителя, или на худой конец, ПРЕКРАТИТЬ действие этого флага в определенный момент времени.
Намекаю: уничтожение хранилища и закрытие контекста сертификата не помогает, и вообще занимаемые при первом вызове криптографии ресурсы не освобождаются - проверял специально.
08.02.2005 14:14:18Василий
В чём проблема-то? Пишите на низком уровне так, как Вам надо, раз Вас не устраивает существующее (в полном соответствии с MSDN) поведение функций simplified level. Вы же сами этим флажком просите не закрывать контекст контейнера - вот он и не закрывается...
08.02.2005 16:26:59Михаил Копачев
НДа-а. Всем спасибо.