Автор: two_oceans 
Ну если включена служба "распространение сертификатов" и носитель именно токен, распознанный как смарт-карта, то "Личное" уже автоматом подтянет сертификат с токена, как только вставите токен.
Ближе к теме - теоретически в CryptoApi на хранилище "личное" свет клином не сошелся и теоретически можно использовать в CertOpenStore другие типы хранилищ. Если сможете использовать токен как хранилище некого типа - получите желаемый результат без махинаций с типами.
Есть тип хранилища CERT_STORE_PROV_SMART_CARD, но с пометкой что не используется. Возможно CERT_STORE_PROV_SERIALIZED или CERT_STORE_PROV_FILENAME подойдет для создания импровизированного хранилища, хотя это и выглядит притянутым за уши.
Собственно, решение у нас простое, но оно оправдано для нас:
Люди заходят на терминальный сервер Windows. Далее в 1С (самописная). Пакетного подписания документов нет (для нас это вредно, надо чтобы каждый вдумчиво подписывался). В каждом документе 1С – кнопка «Подписать».
По кнопке виртуальным принтером получаем (для первой подписи) файл PDF. Далее реализованная на C# COM компонента с помощью CryptoApi: открывает контекст криптопровайдера (и, кстати, не закрывает его, не освобождая до момента закрытия самой 1С – это позволяет обращаться при повторном нажатии кнопки к кешу, и последующее подписание производится мгновенно и не требует повторного ввода пароля), далее перечисляются все контейнеры с флагом UNIQUE, чтобы получить в идентификаторе контейнера, что это Токен, получаем из контейнера контекст сертификата и производим встроенную в PDF открепленную подпись.
Для пользователя всего одна кнопка Подписать. Нет доп диалогов выбора сертификата. То есть интерфейсно все мило. Работать с кешем вынув ключ также не получится (не продвинутому пользователю), так как каждый раз производится опрос контейнеров. И при вставке пользователем другого Токена – будет подпись другим Токеном, так же без доп вопросов. Бизнесс-логика правомерности подписания того или иного документа тем или иным сертификатом реализована в 1С (проверка фирмы, и тд). То есть пользователю важно хранить свой ключ (так как люди разные и пароли по умолчанию не всегда меняются). То есть у нас Токен возведен в высшую ценность, бережется и тд.
Решение было (и есть) рабочее, пока не встал вопрос об усовершенствованной подписи. Конкретно сейчас для нас ее применение не столь необходимо, но как я понимаю руководство, это «красиво», это задел на будущее, да и ПО куплено, так почему бы и нет.
Я, не владея премудростями, решил, что CadesCom – хорошее решение. Проверил тестовые примеры – все отлично работает. Но контекст сертификата для CadesCom свой, и легко получается перебором из своего же типа (CadesCom-ного) хранилища.
Моя же идея сводится к тому, как имея контекст сертификата хоть x509, хоть CERT_CONTEXT CryptoApi подсунуть его CadesCom-у и выполнить подпись. Пока для меня это неразрешимая задача ).
Как мне кажется нужно двигаться в следующем направлении, использовать:
"КриптоПро ЭЦП SDK. Интерфейс языка C. Интерфейс клиентских приложений языка C спроектирован таким образом, чтобы дополнять или замещать функции Crypto API для работы с подписанными сообщениями и предоставляет две группы функций - низкоуровневые функции и упрощённые функции."
Вот пример:
https://cpdn.cryptopro.ru/content/cades/samplesimplifiedapisign.htmlНо как это вызвать из C# я не очень понимаю. Я даже не очень понял, возможно ли просто рядом со своей dll (NET) положить:
В ряде случаев требуется установить только cades.dll или cadescom.dll, не устанавливая при этом КриптоПро ЭЦП SDK полностью. В таких случаях можно воспользоваться следующими дистрибутивами.Не регистрируя как COM. И вызывать просто [DllImport("
cades.dll")]
Отредактировано пользователем 2 апреля 2021 г. 13:01:27(UTC)
| Причина: Не указана