Crypto API
Добрый день ! Подскажите ,пожалуйста, как средствами CryptoApi открыть сертификат с RuToken ? Т.е. хочется сделать CertOpenStore, но чтобы она открыла именно токен, находящийся на данный момент в компьютере.
Вы не авторизованы. Пожалуйста, войдите или зарегистрируйтесь.
Форум Рутокен → Техническая поддержка разработчиков → Crypto API
Страницы 1
Чтобы отправить ответ, нужно авторизоваться или зарегистрироваться
Добрый день ! Подскажите ,пожалуйста, как средствами CryptoApi открыть сертификат с RuToken ? Т.е. хочется сделать CertOpenStore, но чтобы она открыла именно токен, находящийся на данный момент в компьютере.
Добрый день.
Алексей, подскажите, какая перед Вами стоит задача? что Вам необходимо получить в итоге?
Дело в том, что функция CertOpenStore работает с локальным хранилищем.
В рамках интерфейса CryptoAPI в драйверах Rutoken реализован интерфейс Cryptographic Service Provider (CSP), с помощью которого можно получить сертификат как свойство ключевой пары, и зарегестрировать его в локальном хранилище, в нужном разделе.
Кроме того, сертификаты регистрируются в локальном хранилище автоматически после подключения Rutoken по средствам Certificate Propogation Service.
Для каждого пользователя на сервере сохранены данные, зашифрованные его открытым ключом. Кроме того сохранена информация о Issuer и SerialNumber из того сертификата, который использовался для каждого набора зашифрованных данных. При запуске моей программы необходимо установить чей токен воткнут, и расшифровать соответствующие этому пользователю данные. собственно задача - понять, чьи данные отправлять на расшифровку.
Может сохранять с зашифрованными данными открытые ключи и сравнивать его с экспортированным с токена посредствам Active CSP ?
Это можно сделать по средствам CSP.
1. Перебрать доступные контейнеры с подключенного Rutoken:
1.1 CryptAcquireContext(... CRYPT_VERIFYCONTEXT ...);
1.2 CryptGetProvParam(... PP_ENUMCONTAINERS...);
1.3 Для каждого контейнера получить хендл ключевой пары - CryptGetUserKey;
1.4 Получить у ключа свойство сертификата - CryptGetKeyParam(... KP_CERTIFICATE...);
2. Создать контекст из данных сертификата - CertCreateCertificateContext.
3. Получить из контекста сертификата необходимые свойства - CertGetCertificateContextProperty, сравнить с имеющимися.
4. Расшифровать данные по средствам CryptAPI и CSP.
Единственно, не рекомендую Вам использовать открытый ключ ассиметричного алгоритма для шифрования конечных данных - это очень медленная операция по сравнению с симетричным шифрованием.
Эфективнее создать по средствам CSP сессионный ключ, зашифровать им данные, а потом выгрузить его из CSP в зашифрованном на открытом ключе RSA, и сохранить рядом с зашифрованными данными. И в открытом виде положить рядом информацию о владельце сертификата.
О использовании сессионных ключей лучше посмотреть здесь: http://msdn.microsoft.com/en-us/library … S.85).aspx
Спасибо большое, буду пробовать ! Я шифрую от 10 до 24 байт, так что нет смысла связываться с сессионными ключами.
Все получилось, спасибо большое !
Здравствуйте.
Я никак не могу получить хендл ключевой пары в CryptGetUserKey - что нужно указать в параметре dwKeySpec?
Что бы я не указывал, ответ один - NTE_NO_KEY (The key requested by the dwKeySpec parameter does not exist.)
Это зависит от свойств ключевой пары в контейнере.
Тип ключевой пары контейнера задается на этапе его создания, либо указан в шаблоне сертификата.
Возможных варианта два: AT_KEYEXCHANGE и AT_SIGNATURE.
Если при обоих значениях выдается ошибка NTE_NO_KEY, значит в контейнере отсутствует ключевая пара - она либо не сгенерирована, либо не записана в контейнер.
Да, ошибка при обоих значениях AT_KEYEXCHANGE и AT_SIGNATURE.
Как тогда можно получить сертификат (имя ключевого контейнера известно)?
Сертификат, в рамках CryptoAPI, это свойство ключевой пары - KP_CERTIFICATE.
Если в контейнере нет ключей, то контейнер пуст - в нем не может быть сертификата.
Это возможно только в том случае, если ключ либо не был сгенерирован, либо не был записан в контейнер.
Я на некоторое время оставил этот проект и уже не все помню, но, по моему, есть некоторые особенности использования CryptAcquireContext(... CRYPT_VERIFYCONTEXT ...); в части использования параметра CRYPT_VERIFYCONTEXT. Я работал с сертификатами, созданными службой сертификации Windows
Сертификат в контейнере есть, его можно посмотреть через консоль КриптоПро CSP
CRYPT_VERIFYCONTEXT в нашем CSP не позволяет использовать только закрытый ключ (как требует документация MSDN).
Если CryptAcquireContext был вызван с флагом CRYPT_VERIFYCONTEXT, и был получен хендл реального контейнера, то можно получить и хендл ключа, и сертификат.
Ограничения могут быть только при использовании CryptSignHash и т.д.
В других CSP это может быть не так.
Да действительно дело было в параметре CRYPT_VERIFYCONTEXT. Без него в функции CryptAcquireContext все получилось.
Страницы 1
Чтобы отправить ответ, нужно авторизоваться или зарегистрироваться
Форум Рутокен → Техническая поддержка разработчиков → Crypto API