КриптоПро CSP 4.0

127018, Москва, ул. Сущёвский вал, д. 18
Телефон: +7 (495) 995 4820
Факс: +7 (495) 984 0790
http://www.CryptoPro.ru
E-mail: info@CryptoPro.ru

Средство Криптографической Защиты Информации

КриптоПро CSP

Версия 4.0

Руководство программиста
Часть 1
System Program Interface (CryptoSPI)

© OOO "КРИПТО-ПРО", 2000-2016. Все права защищены.
Авторские права на средство криптографической защиты информации КриптоПро CSP и эксплуатационную документацию зарегистрированы в Российском агентстве по патентам и товарным знакам (Роспатент). Свидетельство об официальной регистрации программ для ЭВМ № 2008612300 от 12 мая 2008 года.
Документ входит в комплект поставки программного обеспечения КриптоПРО CSP, и на него распространяются все условия лицензионного соглашения. Без специального письменного разрешения OOO "КРИПТО-ПРО" документ или его часть в электронном или печатном виде не могут быть скопированы и переданы третьим лицам с коммерческой целью.


КриптоПро CSP

Руководство программиста

Средство Криптографической Защиты Информации "КриптоПро CSP 4.0"

СКЗИ "КриптоПро CSP 4.0" реализует российские криптографические алгоритмы и разработано в соответствии с криптографическим интерфейсом фирмы Microsoft - Cryptographic Service Provider (CSP).

КриптоПро CSP

"КриптоПро CSP 4.0" является дальнейшим развитием средства криптографической защиты информации "КриптоПро CSP", разработанного ООО "КРИПТО-ПРО".

Данный документ описывает программный интерфейс СКЗИ "КриптоПро CSP 4.0".

Область применения

Для UNIX-платформ рекомендуется использовать интерфейс CAPILite. В ряде случаев можно встраивать на уровне ядра.

Интеграция "КриптоПро CSP 4.0" с операционной системой Windows позволяет использовать технологии Microsoft с российскими криптографическими алгоритмами для реализации различных защищенных систем документооборота и электронной коммерции на основе Инфраструктуры Открытых Ключей (Public Key Infrastructure), соответствующей международным рекомендациям X.509, RFC 3280, RFC 4491 и Федеральному закону "Об электронной цифровой подписи".

Использование "КриптоПро CSP 4.0" позволяет решить несколько задач:

  • Для корпоративных пользователей - это возможность использования стандартных приложений корпорации Microsoft с надежной российской криптографией.
  • Для системных интеграторов - это возможность создания новых, надежно защищенных приложений с использованием обширного и проверенного временем инструментария корпорации Microsoft.

К стандартным приложениям, которые теперь могут использовать российские алгоритмы электронной цифровой подписи и шифрования, относятся:

  • Центр Сертификации - Microsoft Certification Authority;
  • Электронная почта - Microsoft Outlook;
  • Электронная почта - Microsoft Outlook Express;
  • Средства контроля целостности ПО - Microsoft Authenticode;
  • Защита соединений в Интернете (протокол TLS/SSL);
  • Электронно-цифровая подпись в Word, Excel - Office 2003 или 2007;
  • Электронно-цифровая подпись XML, в том числе, InfoPath из состава Office 2003 или 2007;

См. в этой главе | Важные внешние ссылки
Архитектура и встраивание СКЗИ на Windows/Unix | CRYPTOPROWEB
Функциональность | Конференция Крипто-Про World Wide Web link
Интерфейс криптопровайдера "КриптоПро CSP 4.0" | Использование CryptoAPI в MSDN World Wide Web link
Примеры использования функций "КриптоПро CSP 4.0" |
Особенности создания подписанных CMS сообщений в КриптоПро CSP 3.6 и выше |

КриптоПро CSP Версия: 4.0

Обратная связь для этой статьи

(c) ООО "КРИПТО-ПРО". Все права защищены.


Архитектура и встраивание СКЗИ на Windows/Unix

СКЗИ "КриптоПро CSP 4.0" разработано с учётом существующей в операционной системе Windows архитектурой использования криптографических функций: оно реализует специфицированный Microsoft интерфейс - Cryptographic Service Provider (CSP). В результате оно доступно для использования как в составе стандартного программного обеспечения, так и для встраивания в прикладное программное обеспечение.

Архитектура криптографических функций в Windows

Встраивание СКЗИ "КриптоПро CSP 4.0"

Иерархическая архитектура криптографических функций в операционной системе Windows позволяет использовать российские криптографические алгоритмы, реализованные в "КриптоПро CSP 4.0" на самых различных уровнях.

Отладка в Windows

Для работы с любым отладчиком контроль целостности в драйвере должен быть отключен. Для этого следует в реестре значение HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\CProIntegrity\CheckMode установить в 0. После этого для Windows XP, 2003 необходимо перестартовать сервис, а для Windows 2000 перегрузить машину.

Подключение на уровне CSP в Windows

В ОС Windows СКЗИ "КриптоПро CSP 4.0" может быть непосредственно подключено к прикладному программному обеспечению путем загрузки модуля cpcspi.dll с использованием функции LoadLibrary(). При такой реализации прикладному ПО доступен лишь ограниченный набор низкоуровневых криптографических функций, соответствующий интерфейсу Microsoft CSP.

Подключение на уровне CryptoAPI 2.0 в Windows

"КриптоПро CSP 4.0" может быть подключено к прикладному программному обеспечению (как и любой другой криптопровайдер, поставляемый с ОС Windows) через интерфейс CryptoAPI 2.0, подробное описание которого приведено в программной документации MSDN (Microsoft Developer Network). В этом случае способ выбора криптографического алгоритма в прикладном ПО может определятся информацией, описывающей алгоритм открытого ключа отправителя/получателя, содержащейся в сертификатах открытых ключей Х.509.

Встраивание в ОС Unix

Для подключения СКЗИ к прикладному ПО необходимо пользоваться интерфейсом CAPILite. Подробности в документации на CAPILite.

Встраивание на уровне ядра

Для встраивания на уровне ядра пользуйтесь рекомендациями из Особенности использования интерфейса уровня ядра в OC Linux и Особенности использования интерфейса уровня ядра в Windows .

Функциональность CAPI 2.0

Использование интерфейса CryptoAPI 2.0 в ОС Windows преследует две главные цели:

  • Дать прикладному уровню доступ к криптографическим функциям для генерации ключей, формирования/проверки электронной цифровой подписи, шифрования/расшифрования данных. Эта цель достигается путем изолирования прикладного уровня от уровня реализаций криптографических функций. Прикладным программистам не нужно детально изучать особенности реализации того или иного алгоритма или изменять код в зависимости от алгоритма.
  • Изолирование прикладного уровня от криптографических функций позволяет одновременно использовать разные алгоритмы и различные реализации этих алгоритмов, включая аппаратные.

Функционально интерфейс CryptoAPI 2.0 делится на 5 групп.

Базовые криптографические функции

К базовым функциям относятся функции:

  • Функции инициализации (работы с контекстом). Эти функции предоставляют приложению возможность выбрать определенный криптопровайдер по типу имени или по требуемой функциональности.
  • Функции генерации ключей. Эти функции предназначены для формирования и хранения криптографических ключей различных типов.
  • Функции обмена ключами. Эти функции предназначены для того, чтобы приложения могли обмениваться различными типами ключевой информации для обеспечения взаимодействия между собой.
  • Функции хэширования и ЭЦП. Эти функции предназначены для вычисления значения хэш-функции и формирования/проверки ЭЦП данных.
  • Функции шифрования/расшифрования данных. Эти функции предназначены для выполнения операций шифрования и расшифрования данных.

По своей функциональности базовые функции повторяют низкоуровневый интерфейс CSP.

Функции кодирования/декодирования

Данные функции предназначены для преобразования (кодирования) из внутреннего представления объектов, используемых в CryptoAPI, во внешнее представление и обратно. В качестве внешнего представления объектов используется формат ASN.1 (Abstracy Syntax Notation One), определенный серией рекомендаций X.680. К этой же группе функций можно отнести набор функций, позволяющих расширить функциональность CryptoAPI 2.0 путем реализации и регистрации собственных типов объектов.

Функции работы со справочниками сертификатов

Эта группа функций предназначена для хранения и обработки сертификатов в различных типах справочников. Причем в качестве справочника могут использоваться самые различные типы хранилищ: от простого файла до LDAP.

Высокоуровневые функции обработки криптографических сообщений

Именно эта группа функций (Simplified Message Functions) в первую очередь предназначена для использования в прикладном ПО. С помощью этих функций можно:

  • Зашифровать/расшифровать сообщение от одного пользователя к другому.
  • Подписать данные.
  • Проверить подпись данных.

Эти функции (как и функции низкого уровня) оперируют сертификатами открытых ключей X.509 для адресации отправителя/получателя данных. В качестве формата данных используется формат PKCS#7 (RFC2315) или CMS (RFC2630) в Windows 2000.

Низкоуровневые функции обработки криптографических сообщений

Данная группа функция (Low Level Message Functions) предназначена для аналогичных целей, что и группа высокоуровневых функций, но обладает большей функциональностью. Вместе с тем большая функциональность требует от прикладного программиста более детальных знаний в области прикладной криптографии.

Использование COM интерфейсов

"КриптоПро CSP 4.0" может быть использовано из COM интерфейсов, разработанных Microsoft.

  • CAPICOM 1.0 (CAPICOM 2.0);
  • Certificate Services;
  • Certificate Enrollment Control.

Certificate Enrollment Control

COM интерфейс Certificate Enrollment Control (реализованный в файле xenroll.dll) предназначен для использования ограниченного количества функций CryptoAPI 2.0, связанных с генерацией ключей, запросов на сертификаты открытых ключей и обработкой сертификатов, полученных от Центра Сертификации, с использованием языков программирования Visual Basic, C++, JavaScript, VBScript и среды разработки Delphi.

Именно этот интерфейс используют различные Центры Сертификации (Verisign, Thawte и т. д.) при формировании сертификатов открытых ключей пользователей на платформе Windows.

CAPICOM

CAPICOM (реализованный в файле capicom.dll) предоставляет COM интерфейс, использующий основные функции CryptoAPI 2.0. Этот компонент является добавлением к COM интерфейсу Certificate Enrollment Control (xenroll.dll), который реализуют клиентские функции генерации ключей, запросов на сертификаты открытых ключей и обмена с центром сертификации.

С выпуском данного компонента стало возможным использование функций формирования и проверки электронной цифровой подписи, построения и проверки цепочек сертификатов, взаимодействия с различными справочниками сертификатов (включая Active Directory) с использованием Visual Basic, C++, JavaScript, VBScript и среды разработки Delphi. Использование CAPICOM позволяет реализовать функциональность "тонкого" клиента в интерфейсе броузера Internet Explorer.

Компонент CAPICOM является свободно распространяемым и поставляется в составе Redistributable инструментария разработчика Microsoft Platform SDK.

Certificate Services

Certificate Services включает в себя несколько COM интерфейсов, позволяющих изменить функциональность Центра Сертификации, входящего в состав ОС Windows 2000 Server. При помощи данных интерфейсов возможно изменить:

  • обработку поступающих от пользователей запросов на сертификаты
  • состав данных (в том числе дополнений X.509), записываемых в издаваемые центром сертификаты
  • способ публикации (хранения) изданных центром сертификатов.

Использование протокола TLS в прикладном ПО

Кроме использования протокола TLS в интерфейсе Internet Explorer, прикладное программное обеспечение может использовать протокол TLS с СКЗИ "КриптоПро CSP 4.0" для аутентификации и защиты данных, передаваемых по собственным протоколам на основе TCP/IP и HTTPS.

Примеры WebClient и WebServer для встраивания протокола TLS входят в комплект примеров, поставляемых вместе с Platform SDK.

Примеры использования средств криптографической защиты

СКЗИ "КриптоПро CSP 4.0" поставляется с тестовым программным обеспечением, содержащим примеры вызовов основных функций CryptoAPI 2.0. Большое количество примеров использования функций CryptoAPI 2.0, CAPICOM, Certificate Services содержится в документации MSDN и в инструментарии разработчика Platform SDK.

На сервере Крипто-Про ведется Конференция Крипто-Про World Wide Web link по вопросам использования криптографических функций и сертификатов открытых ключей.

Заключение

СКЗИ "КриптоПро CSP 4.0" позволяет использовать стойкие сертифицированные средства криптографической защиты информации в составе обширного инструментария и программного обеспечения корпорации Microsoft, для реализации различных защищенных систем документооборота и электронной коммерции, на основе Инфраструктуры Открытых Ключей (Public Key Infrastructure), соответствующей международным рекомендациям X.509, RFC 3280.


Функциональность

Основные функции "КриптоПро CSP 4.0"

Основные функции, реализуемые "КриптоПро CSP 4.0":

  • генерация ключей подписи (256 бит и 512 бит), ключей обмена (256 бит и 512 бит), ключей шифрования (256 бит),
  • формирование ключей проверки подписи (512 бит для ГОСТ Р 34.10-2012 с длиной ключа подписи 256 бит (ГОСТ Р 34.10-2001) и 1024 бита для ГОСТ Р 34.10-2012 с длиной ключа подписи 512 бит);
  • формирование закрытых ключей на следующие типы носителей:
    • дискета 3,5";
    • процессорные карты MPCOS-EMV и российские интеллектуальные карты (РИК) с использованием считывателей смарт-карт, поддерживающие протокол PS/SC (GemPlus GCR-410, Towitoko, Oberthur OCR126);
    • индикаторы Touch-Memory DS1993 - DS1996 с использованием устройств Аккорд-АМДЗ, электронный замок "Соболь", устройство чтения индикаторов Touch-Memory DALLAS;
    • электронный ключ с интерфейсом USB;
    • сменный носитель с интерфейсом USB;
    • реестр Windows, локальный диск ОС UNIX.
  • возможность хранения сертификатов открытых ключей в ключевом контейнере;
  • возможность генерации ключей с различными параметрами в соответствии с ГОСТ Р 34.10-2001 и ГОСТ Р 34.10-2012 ("Информационная технология. Криптографическая защита информации. Процессы формирования и проверки электронной цифровой подписи.");
  • хэширование данных в соответствии с ГОСТ Р 34.11-94 и ГОСТ Р 34.11-2012 ("Информационная технология. Криптографическая защита информации. Функция хэширования.");
  • шифрование данных во всех режимах, определенных ГОСТ 28147-89 ("Системы обработки информации. Защита криптографическая.");
  • имитозащита данных в соответствии с ГОСТ 28147-89;
  • формирование электронной цифровой подписи в соответствии с ГОСТ Р 34.10-2001 и ГОСТ Р 34.10-2012;
  • поддержка функций, режимов, параметров, определённых в RFC 4357;
  • опциональное использование пароля (пин-кода) для дополнительной защиты ключевой информации;
  • реализация мер защиты от НСД ключевой информации пользователя.

Операционные системы

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

На платформах Microsoft Windows 2000/XP, используемых с СКЗИ "КриптоПро CSP 4.0", должна быть произведена установка следующих двух пакетов обновлений:
  • Microsoft Security Bulletin MS02-048. Flaw in Certificate Enrollment Control Could Allow Deletion of Digital Certificates (Q323172). August 28, 2002 World Wide Web link
  • Microsoft Security Bulletin MS02-050. Certificate Validation Flaw Could Enable Identity Spoofing (Q328145). September 09, 2002 World Wide Web link

Примечание 1. Полный перечень операционных систем и дополнительные требования, необходимые для функционирования СКЗИ, приведены в документе ""КриптоПро CSP 4.0". Описание реализации", ЖТЯИ.00087-01 90 01.

Примечание 2. Порядок и сроки эксплуатации операционных систем, в среде которых функционирует СКЗИ "КриптоПро CSP 4.0", определяются производителями операционных систем.

Примечание 3. При выборе ОС необходимо учитывать следующие сроки поддержки и окончания эксплуатации операционных систем по данным фирмы Microsoft на 03.07.2002 г. (Windows Desktop Product Life Cycle Support and Availability Policies for Businesses World Wide Web link ):

ОС | Поддержка | Окончание эксплуатации
Microsoft Windows 2000 | 31 марта 2005 г. | 31 марта 2007 г.
Microsoft Windows XP | 31 декабря 2006 г. | 31 декабря 2008 г.
Microsoft Windows 2003 | 30 июня 2008 г. | 30 июня 2010 г.

Интеграция с прикладным программным обеспечением

О способах использования "КриптоПро CSP 4.0" см. в разделе Архитектура и встраивание СКЗИ на Windows/Unix .

Удостоверяющий центр

На базе средства криптографической защиты информации "КриптоПро CSP 4.0" компания Крипто-Про выпускает программный комплекс удостоверяющего центра КриптоПро УЦ, реализующий Инфраструктуру Открытых Ключей.

Удостоверяющий центр КриптоПро УЦ - это комплекс программных средств, разработанных на основе служб сертификации операционной системы Windows 2000 Server.

Основные функции, выполняемые с помощью КриптоПро УЦ:

  • Регистрация пользователей
  • Изготовление сертификатов открытых ключей
  • Ведение реестра сертификатов открытых ключей
  • Управление сертификатами открытых ключей
  • Предоставление владельцам сертификатов функций генерации ключей и управления личными сертификатами

Удостоверяющий центр КриптоПро УЦ обеспечивает:

  • Выполнение процедуры генерации личных закрытых и открытых ключей ЭЦП и шифрования на рабочем месте пользователя;
  • Формирование запроса на сертификат нового открытого ключа на рабочем месте пользователя;
  • Выполнение процедуры регистрации электронных запросов от пользователей на сертификаты открытых ключей в Центре регистрации УЦ;
  • Формирование электронных сертификатов открытых ключей пользователей в соответствии с рекомендациями Х.509 версии 3 и RFC 3280, позволяющими с помощью криптографических методов (ЭЦП) централизованно заверять соответствие открытого ключа и атрибутов определенному пользователю;
  • Формирование и доставку зарегистрированным пользователям списка отозванных сертификатов открытых ключей пользователей.


Особенности создания подписанных CMS сообщений в КриптоПро CSP 3.6 и выше

Для того, чтобы создаваемые с помощью CryptoAPI сообщения могли быть впоследствии дополнены до форматов усовершенствованной ЭЦП (CAdES-T, CAdES-X Long Type 1 и других), они должны как минимум соответствовать базовому формату усовершенствованной ЭЦП (CAdES BES).

Формат электронной подписи CAdES BES требует наличия в подписанном сообщении подписанного атрибута, идентифицирующего сертификат подписывающего:

  • SigningCertificate (для подписей с алгоритмом хэширования SHA1),
  • SigningCertificateV2 (для подписей с остальными алгоритмами хэширования).

Поскольку после создания подписи нельзя добавлять или изменять подписанные атрибуты, КриптоПро CSP при создании подписанного сообщения с использованием алгоритма ГОСТ Р 34.10/34.11 добавляет к нему подписанный атрибут SigningCertificateV2.

Также в сообщение добавляется отметка о времени создания подписи в виде подписанного атрибута signingTime (время в атрибуте указывается по часам локального компьютера).

Особенности добавления атрибутов

Добавление атрибутов SigningCertificateV2 и signingTime затрагивает работу следующих функций: CryptMsgOpenToEncode, CryptMsgControl, CryptMsgCalculateEncodedLength и CryptSignMessage.

Атрибуты SigningCertificateV2 и signingTime не будут добавлены в подписанное сообщение, если выполняется хотя бы одно из следующих условий:

  • В параметрах вызова функции уже указан хотя бы один из подписанных атрибутов: SigningCertificate, SigningCertificateV2 или otherSigningCertificate.
  • Алгоритм подписи не ГОСТ Р 34.10/34.11

  • Не удаётся найти сертификат лица, создающего электронную подпись, необходимый для вычисления значения атрибута SigningCertificateV2

Поиск сертификата ключа электронной подписи

В функцию CryptSignMessage сертификат ключа электронной подписи передаётся в качестве аргумента,в то время как при использовании функций CryptMsgOpenToEncode, CryptMsgCalculateEncodedLength, CryptMsgControl производится его поиск в следующих местах:

  • В контейнере закрытого ключа
  • В коллекции сертификатов, добавленных в подписанное сообщение
  • В хранилищах "Личные" ("My") текущего пользователя и локального компьютера (если не указан флаг CPCMSG_CADES_DISABLE_CERT_SEARCH)

Для поиска сертификата используется имя издателя и серийный номер, заданный в качестве идентификатора подписывающего при вызове функции. Если в качестве идентификатора подписывающего указан идентификатор ключа, поиск сертификата не ведётся и атрибуты в сообщение не добавляются.

Отключение добавления атрибутов

Существуют следующие способы отключить добавление атрибутов SigningCertificateV2 и signingTime в подписанное сообщение:

  • Задать флаг, отключающий добавление атрибутов (CPCMSG_CADES_DISABLE/CPCRYPT_MESSAGE_CADES_DISABLE)
  • Установить параметр реестра, отключающий добавление атрибутов (AddEsAttribute)

Параметр dwFlags для функций CryptMsgOpenToEncode, CryptMsgCalculateEncodedLength, CryptMsgControl может содержать дополнительные флаги, определённые в файле WinCryptEx.h:

Флаг | Описание
CPCMSG_CADES_DISABLE | Отключает добавление атрибутов. Данный флаг не может быть указан одновременно с CPCMSG_CADES_STRICT.
CPCMSG_CADES_STRICT | Если не удалось добавить атрибуты, функция вернёт ошибку. Данный флаг не может быть указан одновременно с CPCMSG_CADES_DISABLE.
CPCMSG_CADES_DISABLE_CERT_SEARCH | Отключает поиск сертификата подписывающего в хранилищах "Личные" ("My") текущего пользователя и локального компьютера.

Параметр dwFlags для функции CryptSignMessage может содержать дополнительные флаги, определённые в файле WinCryptEx.h:

Флаг | Описание
CPCRYPT_MESSAGE_CADES_DISABLE | Отключает добавление атрибутов. Данный флаг не может быть указан одновременно с CPCRYPT_MESSAGE_CADES_STRICT.
CPCRYPT_MESSAGE_CADES_STRICT | Если не удалось добавить атрибуты, функция вернёт ошибку. Данный флаг не может быть указан одновременно с CPCRYPT_MESSAGE_CADES_DISABLE.

Добавление атрибутов на всём компьютере регулируется параметром реестра AddEsAttribute. Если данный параметр отсутствует, то добавление дополнительных атрибутов будет производиться. Для того, чтобы отключить добавление атрибутов, нужно добавить параметр AddEsAttribute типа DWORD и значением 0 в ветку реестра "HKEY_LOCAL_MACHINE\SOFTWARE\Crypto Pro\Cryptography\CurrentVersion\Parameters".


Криптографические объекты СКЗИ «КриптоПро CSP» и их синхронизация

Построение СКЗИ «КриптоПро CSP» следует идеологии Microsoft CryptoAPI v1.0 и использует криптографические объекты трех типов:

  • Криптопровайдер, криптографический контекст
  • Криптографический ключ
  • Объект хэширования

Использование CryptoAPI в MSDN World Wide Web link

Объекты идентифицируются дескриптором, работа с объектами определяется интерфейсом СКЗИ «КриптоПро CSP».

Общая схема работы с объектами

Общая схема организации работы с криптографическими объектами – создание контекста, создание ассоциированных с ним криптографических объектов. Перенос дескрипторов из одного контекста в другой не допускается. Объекты могут уничтожаться самостоятельно. При уничтожении контекста все ассоциированные с ним объекты уничтожаются автоматически.

Возможность переноса объектов между контекстами обеспечивается с помощью данных, получаемых функцией экспорта ключей, а также с помощью значения хэш-функции, получаемого и устанавливаемого в объект хэширования функциями CPGetHashParam() и CPSetHashParam().

Способы организации многопоточной работы

Многопоточная обработка с использованием СКЗИ «КриптоПро CSP» может быть организована двумя способами:

  • Создание криптографического контекста и необходимых криптографических объектов для каждого потока.
  • Использование единого контекста в нескольких потоках с разделением объектов между потоками.

Первый подход универсален и может использоваться без дополнительных ограничений на синхронизацию объектов.

Второй связан с необходимостью синхронизации объектов криптопровайдера. Если поток вызывает функцию с объектом, блокированным другим потоком, функция возвращает ошибку с кодом ERROR_BUSY (0xaa).

В следующей таблице определены методы блокировки объектов в криптопровайдере «КриптоПро CSP».

Таблица блокировок криптографических объектов «КриптоПро CSP»

Имя функции | hProv | hKey | hExpKey | hHash | Примечание
CPCAcquireContext(), CPAcquireContext() | LOCK_WRITE | -- | -- | -- |
CPCCreateHash(), CPCreateHash() | LOCK_READ | LOCK_READ | -- | -- |
CPCDecrypt(), CPDecrypt() | LOCK_READ | LOCK_READ LOCK_WRITE | -- | LOCK_READ LOCK_WRITE | (dwFlags&CP_CRYPT_NOKEYWLOCK) ? CRWLOCK_READ : CRWLOCK_WRITE
CPCDeriveKey(), CPDeriveKey() | LOCK_READ | -- | -- | LOCK_WRITE |
CPCDestroyHash(), CPDestroyHash() | LOCK_READ | -- | -- | LOCK_WRITE |
CPCDestroyKey(), CPDestroyKey() | LOCK_READ | LOCK_WRITE | -- | -- |
CPCDuplicateHash(), CPDuplicateHash() | LOCK_READ | -- | -- | LOCK_READ |
CPCDuplicateKey(), CPDuplicateKey() | LOCK_READ | LOCK_READ | -- | -- |
CPCEncrypt(), CPEncrypt() | LOCK_READ | LOCK_READ LOCK_WRITE | -- | LOCK_READ LOCK_WRITE | (dwFlags&CP_CRYPT_NOKEYWLOCK) ? CRWLOCK_READ : CRWLOCK_WRITE
CPCExportKey(), CPExportKey() | LOCK_READ | LOCK_READ | LOCK_READ LOCK_WRITE | -- | (dwBlobType == SIMPLEBLOB) && (dwFlags&CP_CRYPT_NOKEYWLOCK) ? CRWLOCK_READ : CRWLOCK_WRITE
CPCGenKey(), CPGenKey() | LOCK_READ | -- | -- | -- |
CPCGenRandom(), CPGenRandom() | LOCK_READ | -- | -- | -- |
CPCGetHashParam(), CPGetHashParam() | LOCK_READ | -- | -- | LOCK_WRITE |
CPCGetKeyParam(), CPGetKeyParam() | LOCK_READ | LOCK_WRITE | -- | -- |
CPCGetProvParam(), CPGetProvParam() | LOCK_READ LOCK_WRITE | -- | -- | -- | IsReadOnlyProvParam (dwParam) ? LOCK_READ : LOCK_WRITE
CPCGetUserKey(), CPGetUserKey() | LOCK_READ | -- | -- | -- |
CPCHashData(), CPHashData() | LOCK_READ | -- | -- | LOCK_WRITE |
CPCHashSessionKey(), CPHashSessionKey() | LOCK_READ | LOCK_WRITE | -- | LOCK_WRITE |
CPCImportKey(), CPImportKey() | LOCK_READ LOCK_WRITE | LOCK_READ LOCK_WRITE | -- | -- | hProv: bUKChange ? LOCK_WRITE : LOCK_READ, где bUKChange = IsPRIVATEKEYBLOB(pbData, dwDataLen); hKey: ((pbData[0] == SIMPLEBLOB) || (pbData[0] == PUBLICKEYBLOB) || ((pbData[0] == DIVERSKEYBLOB) && (CALG_PRO_DIVERS == (*(DWORD*)(pbData + sizeof(BLOBHEADER))))))) ? CRWLOCK_READ : CRWLOCK_WRITE
CPCReleaseContext(), CPReleaseContext() | LOCK_WRITE | -- | -- | -- |
CPCSetHashParam(), CPSetHashParam() | LOCK_READ | -- | -- | LOCK_WRITE |
CPCSetKeyParam(), CPSetKeyParam() | LOCK_READ LOCK_WRITE | LOCK_WRITE | -- | -- | bUKChange ? LOCK_WRITE : LOCK_READ, где bUKChange = IsPrivateKeyParam(dwParam, pbData);
CPCSetProvParam(), CPSetProvParam() | LOCK_WRITE | -- | -- | -- |
CPCSignHash(), CPSignHash() | LOCK_READ | -- | -- | LOCK_WRITE |
CPCVerifySignature(), CPVerifySignature() | LOCK_READ | LOCK_WRITE | -- | LOCK_WRITE |

Объекты ключей и хэширования, как видно из таблицы, в основном блокируются на запись, что связано с динамических характером обработки этих объектов.

Криптографические объекты при многопоточной обработке

Схема блокирования объектов СКЗИ «КриптоПро CSP» обеспечивает их безопасное использование при конкурентном выполнении операций в различных потоках. Вместе с тем, такое выполнение операций может приводить к неопределённому результату не вследствие ограничений СКЗИ или приложений, а по сути исполняемых операций. Например, результаты вызова функций CPEncrypt() зависят от предыдущих вызовов. Поэтому при многопоточной обработке пользователю следует самостоятельно обеспечивать потоковую безопасность (thread safe) и синхронизацию потоков тем способом, который он сочтёт нужным.


Кодировки в функциях "КриптоПро CSP 4.0"

Особенности кодировки в функциях

При передаче текстовых строк в различные интерфейсы провайдера и при их получении может возникать вопрос об используемой кодировке. Рекомендации по встраиванию:

  • использовать только интерфейсы CAPI 1.0 (Crypt) и CAPI 2.0 (последний предпочтительней из-за "белого списка" функций)
  • на Windows собирать в режиме Unicode, а не MultiByte
  • по возможности пользоваться только widechar-вариантами функций (например, CryptAcquireContextW)
  • разработчики кроссплатформенных приложений должны помнить, что wchar_t - это int и имеет разную длину на разных платформах
  • widechar-строки имеют кодировку UTF-16LE или UTF-32LE в зависимости от платформы
  • для конвертации строк multibyte / widechar надо пользоваться функциями WideCharToMultiByte / MultiByteToWideChar
  • рекомендуется использовать только ASCII-символы в именах контейнеров и паролях, то есть не использовать русские буквы
  • в остальных случаях надо использовать кодировки по описаниям ниже
Для ядра провайдера (Crypt/CP/CPC) используется кодировка CP_ACP.
Для функций CAPI 2.0 и библиотек cpsuprt.dll / librdrsup.so соглашения в API могут измениться, некоторые детали в таблице ниже.

Функция | Кодировка Windows | Кодировка *nix
CryptAcquireContextA CryptAcquireContextW | CP_ACP | подразумевается CP_ACP
CertOpenSystemStore* CertOpenSystemStoreA CertOpenSystemStoreW | CP_ACP CP_ACP | CP_ACP CP_ACP
FormatMessage** FormatMessageA FormatMessageW | CP_ACP CP_ACP | CP_ACP CP_ACP
CertNameToStrA CertNameToStrW | CP_ACP | CP_UTF8
CryptGetProvParam | CP_ACP | CP_ACP
CertRDNValueToStrA CertRDNValueToStrW | CP_ACP | CP_ACP
CryptVerifySignatureA CryptVerifySignatureW | CP_ACP | CP_ACP
CryptSignHashA CryptSignHashW | CP_ACP | CP_ACP
CryptBinaryToStringA CryptBinaryToStringW | CP_ACP | подразумевается CP_ACP
CryptGetDefaultProviderA CryptGetDefaultProviderW | CP_ACP | подразумевается CP_ACP
CryptStringToBinaryA CryptStringToBinaryW | CP_ACP | подразумевается CP_ACP
CertGetNameStringA CertGetNameStringW | CP_ACP | CP_ACP
*CertOpenSystemStore устаревший символ - только для временной обратной совместимости
**FormatMessage будет объявлен устаревшим и сохранится только для временной обратной совместимости

Согласно документации Microsoft на Windows CP_ACP подразумевает использование текущей установленной по умолчанию кодировки ANSI, для *nix - CP1251.


Сроки действия долговременных ключей в "КриптоПро CSP 4.0"

Особенности контроля сроков действия долговременных ключей

В "КриптоПро CSP 4.0" реализован контроль сроков действия долговременных ключей. Возможность использования ключа, срок действия которого истёк, для различных операций зависит от параметров настройки провайдера.

Параметром, определяющим разрешенные операции для ключа, срок действия которого истёк, является параметр ControlKeyTimeValidity. Данный параметр может принимать значения 0, 1 и 2.

Значение параметра ControlKeyTimeValidity | Эффект
0 | Все операции разрешены.
1 | Запрещено формирование ЭП и зашифрование. Разрешено расшифрование ранее зашифрованных сообщений. Это значение установлено по умолчанию.
2 | Все операции запрещены.

Указанный параметр может быть изменён путём редактирования ключей реестра Windows:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Crypto Pro\Cryptography\CurrentVersion\Parameters\ControlKeyTimeValidity (для 64-битных операционных систем),
HKEY_LOCAL_MACHINE\SOFTWARE\Crypto Pro\Cryptography\CurrentVersion\Parameters\ControlKeyTimeValidity (для 32-битных операционных систем);

либо путём вызова утилиты cpconfig (для *nix-подобных ОС):
./cpconfig -ini '\config\parameters' -add long ControlKeyTimeValidity <значение>

Необходимо отметить, что при включённом режиме усиленного контроля использования ключей значение ControlKeyTimeValidity полагается равным 2 вне зависимости от указанного.

Информация о сроке действия ключей может быть получена путём вызова функции CryptGetKeyParam с параметром KP_NOTAFTER. Эта функция возвращает дату окончания действия ключей AT_SIGNATURE/AT_KEYEXCHANGE в виде структуры FILETIME. Дата окончания действия ключа может определяться по времени создания ключа и по сертификату в контейнере.

При создании ключа срок действия определяется равным 3 годам для неэкспортируемых ключей, хранящихся на функциональных ключевых носителях (ФКН) или в КриптоПро HSM. Сроки действия всех остальных ключей составляют 15 месяцев. Срок окончания действия ключа записывается в расширение контейнера.

При наличии сертификата в контейнере срок действия ключа определяется на основании поля PrivateKeyUsagePeriod (при наличии), либо при его отсутствии сроком начала действия сертификата (3 года с начала при использовании неэкспортируемых ключей, хранящихся на ФКН или в КриптоПро HSM, и 15 месяцев для прочих ключей).

Итоговое возвращаемое значение срока действия ключа определяется как наименьшее значение среди описанных выше. При одновременном отсутствии расширений контейнера и сертификата возвращаемое значение равно -1.

Для всех импортированных долговременных ключей срок действия определяется как 15 месяцев с момента импорта.

Также возможна настройка определения срока действия ключа с использованием только сертификата или только расширения контейнера. Это достигается путём установки дополнительного расширения PrivateKeyTimeValidityControlMode в контейнер.

Расширение PrivateKeyTimeValidityControlMode имеет объектный идентификатор 1.2.643.2.2.37.3.11 и задаётся следующей ASN.1-структурой.

PrivateKeyTimeValidityControlMode ::= BIT STRING {
pktvcmUseCertificate(0),pktvcmUseContainer(1)
}

Установить расширение можно с помощью утилиты csptest. Следующий пример выключает оба типа контроля срока действия ключа.
csptest -noerrorwait -notime -oid -get_param ct:1.2.643.2.2.37.3.11 -set_param 03020600 -container "\\.\HDIMAGE\test" -provtype 81 -provider "Crypto-Pro GOST R 34.10-2012 Strong Cryptographic Service Provider"

Для проверки сроков действия только по сертификату в переменную -set_param нужно передать значение 03020680, только по расширению контейнера - 03020640, по расширению контейнера и по сертификату - 030206С0.

Для установки расширения также можно воспользоваться функцией CryptSetProvParam с параметром PP_CONTAINER_EXTENSION.

Удалить расширение можно с помощью утилиты csptest:
csptest -noerrorwait -notime -oid -del_param ct:1.2.643.2.2.37.3.11 -container "\\.\HDIMAGE\test" -provtype 81 -provider "Crypto-Pro GOST R 34.10-2012 Strong Cryptographic Service Provider"

Также для удаления расширения можно воспользоваться функцией CryptSetProvParam с параметром PP_CONTAINER_EXTENSION_DEL.


Интерфейс криптопровайдера "КриптоПро CSP 4.0" уровня ядра ОС

Функции, структуры, параметры внешнего интерфейса криптопровайдера "КриптоПро CSP 4.0" уровня ядра ОС

  • Инициализация и параметры криптопровайдера
  • Структуры данных, используемые в режиме ядра ОС
  • Функции генерации и работы с ключами
  • Функции шифрования/расшифрования данных
  • Функции хэширования и ЭП
  • Особенности использования интерфейса уровня ядра в Windows
  • Особенности использования интерфейса уровня ядра в OC Linux


Инициализация и параметры криптопровайдера

Перечисленные функции предназначены для установления сессии прикладного ПО с криптопровайдером и получения (установки) параметров сессии.

Функции | Описание
CPCGetDefaultConfig | Функция CPCGetDefaultConfig используется для упрощения создания структуры настроек криптопровайдера.
CPCAcquireContext | Функция CPCAcquireContext() используется для создания дескриптора криптопровайдера с именем ключевого контейнера, определённым параметром pszContainer.
CPCReleaseContext | Функция CPCReleaseContext() используется для удаления дескриптора криптопровайдера, созданного CPCAcquireContext().
CPCGetProvParam | Функция CPCGetProvParam() получает параметры криптопровайдера.
CPCSetProvParam | Функция CPCSetProvParam() устанавливает параметры криптопровайдера.
CPCCreateProvider | Функция CPCCreateProvider() используется для инициализации и настройки криптопровайдера, и для получения таблицы остальных его функций.
CPCDestroyProvider | Функция CPCDestroyProvider() используется для завершения работы с провайдером и освобождения всех ресурсов, занятых вызовом CPCCreateProvider().
CPCInitMemoryLF | Функция создания безблокировочного менеджера памяти. Создает арену, которую можно использовать в настройках провайдера при его создании функцией CPCCreateProvider.


CPCGetDefaultConfig

Функция CPCGetDefaultConfig используется для упрощения создания структуры настроек криптопровайдера.

DWORD CPCAPI CPCGetDefaultConfig(
  LPCPC_CONFIG pConfig,
  LPVOID pvReserved
);

Аргументы

pConfig
[in, out] Указатель на созданную пользователем структуру CPC_CONFIG_. В этой структуре обязательно должен быть задан член cbSize, остальные члены в результате выполнения функции будут заполнены значениями по умолчанию (см. ниже).
pvReserved
[in] Зарезервирован для использования в будущем. Должен быть равен NULL.

Примечания

Функция CPCGetDefaultConfig заполняет созданную пользователем структуру CPC_CONFIG_ настройками по умолчанию.
Настройки по умолчанию:

Член CPC_CONFIG_ | Описание
LPCPC_MEMORY_ARENA pArena | Не изменяется. Должен быть задан пользователем до или после вызова данной функции. Можно использовать простой менеджер памяти, предоставляемый функцией CPCInitMemoryLF.
CPC_FAST_CODE FuncStruct

Windows/Linux/FreeBSD 8.2 или выше: Заполняется стандартными функциями сохранения/восстановления FPU/MMX/SSE/AVX.

Solaris amd64: Настраивается на использование SSSE3 и устанавливается флаг CSP_FAST_CODE_DISABLE_AVX.

Solaris ia32 и FreeBSD до 8.1: не имеют стандартных возможностей для сохранения/восстановления FPU/MMX/SSE/AVX, устанавливается флаг CPC_FAST_CODE_NO.

CPC_LOG_CONFIG logConfig

Windows: Устанавливается уровень вывода сообщений, включающий ошибки и критические ошибки, задаются необходимые Callback-функции. Данные Callback-функции выводят сообщения с помощью функции DbgPrint и могут быть прочитаны, в отладчике уровня ядра.

Linux/FreeBSD/Solaris: Не устанавливаются, должен быть задан пользователем.

CPC_HARDWARE_RNG hardwareRNG | Заполняется нулями. При необходимости использования аппаратного датчика случайных чисел пользователь должен сам реализовать соответствующие функции.
CPC_INTERLOCKED_FUNCS interlockedFuncs | Заполняется нулями, поскольку используется только на процессорах ARM и sparc-v8 (32).
CPC_LOCK_FUNCS lockFuncs

Windows: R/W блокировки ExAcquireResourceSharedLite/ExAcquireResourceSharedLite совместно с CriticalRegion, поэтому без флага CRYPT_NOSERIALIZE CSP может быть вызван только при IRQL <= APC_LEVEL.

Linux/FreeBSD/Solaris: Заполняется нулями. При этом пользователь должен, либо самостоятельно реализовать соответствующие callback функции, либо обеспечить недопущение параллельного вызова функций, влияющих на глобальное состояние провайдера (CPCAcquireContext, CPCReleaseContext, CPCSetProvParam (PP_USE_HARDWARE_RNG, PP_RANDOM)).

CPC_TIME_FUNCS timeFuncs | Задаются необходимые Callback-функции.
CPC_ALG_PARAMS algParams | Заполняется нулями, что обеспечивает использование параметров алгоритмов по умолчанию.
DWORD MaxHandles | Устанавливается равным значению по умолчанию.
DWORD dwTesterPeriod | Устанавливается равным значению по умолчанию.
DWORD dwTesterTimeout | Устанавливается равным значению по умолчанию.
const TCHAR *license; | Заполняется драйверной лицензией на "КриптоПро CSP 4.0", если таковая установлена, или NULL в противном случае.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
E_INVALIDARG | Неверно заданы параметры.

См. также

CPCCreateProvider, CPC_CONFIG_


CPCAcquireContext

Функция CPCAcquireContext() используется для создания дескриптора криптопровайдера с именем ключевого контейнера, определённым параметром pszContainer.

DWORD CPCAPI CPCAcquireContext(
  HCRYPTMODULE hCSP,
  HCRYPTPROV * phProv,
  CHAR * pszContainer,
  DWORD dwFlags,
  PVTABLEPROVSTRUC pVTable
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
phProv
[out] Адрес, по которому функция копирует дескриптор криптопровайдера.
pszContainer
[in] Имя ключевого контейнера. Так как в режиме ядра ОС использование закрытых ключей на носителях невозможно, параметр всегда равен NULL.
dwFlags
[in] Параметр имеет нулевое или одно из следующих значений:
Значение dwFlags | Описание
CRYPT_VERIFYCONTEXT | Приложение не имеет доступа к закрытым ключам ключевого контейнера. Флаг используется в приложениях, в которых требуется только проверка цифровой подписи. Операции, обычно необходимые в этом случае, получение дескрипторов открытых ключей, хэширование и проверка подписи. При вызове функции CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link с этим флагом криптопровайдер не требует от пользователя ввода ключевой информации. Параметр pszContainer игнорируется, но рекомендуется устанавливать его значение в NULL.
CRYPT_SILENT | Флаг, запрещающий криптопровайдеру "КриптоПро CSP 4.0" использовать какой-либо пользовательский интерфейс (UI) при выполнении операций с данным контекстом. Если дальнейшие вызовы функций криптопровайдера требуют отображения графического интерфейса, то криптопровайдер возвратит ошибку NTE_SILENT_CONTEXT.
CRYPT_NOSERIALIZE | Флаг, запрещающий криптопровайдеру "КриптоПро CSP 4.0" использовать ждущие блокировки при операциях создания/удаления объектов в данном контексте. При этом ответственность за недопущение параллельного вызова таких функций берёт на себя приложение. Параллельные обращения к таким функциям над одним и тем же контекстом возвращают ошибку.
CRYPT_TOKEN_SHARED | Флаг контекста взаимодействия с ключевым носителем в режиме разделения секрета, флаг предназначен для взаимодействия с функциональными ключевыми носителями по протоколам, разработанным ООО "КРИПТО-ПРО".
pVTable
[in] Указатель на структуру _VTABLEPROVSTRUC , которая содержит список callback функций, представляемых операционной системой для использования криптопровайдером.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
ERROR_BUSY | Ключевой контейнер с данным именем был создан иным процессом и в настоящее время не может использоваться данным процессом. Если эта ошибка возникает при обработке контейнера в одном процессе, разрешить коллизию можно вызвав функцию CPCReleaseContext().
NTE_BAD_FLAGS | Некорректное значение параметра dwFlags.
NTE_BAD_KEYSET | Ключевой контейнер не был открыт или не существует.
NTE_BAD_KEYSET_PARAM | Используется некорректное значение параметра pszContainer. Ошибка также может возникнуть при открытии с флагом CRYPT_SILENT и неоднозначности в выборе носителя.
NTE_BAD_SIGNATURE | Не прошла проверка цифровой подписи DLL криптопровайдера. DLL или цифровая подпись искажены.
NTE_EXISTS | Параметр dwFlags установлен в CRYPT_NEWKEYSET, а ключевой контейнер уже существует.
NTE_KEYSET_ENTRY_BAD | Ключевой контейнер, соответствующий pszContainer найден, но искажён.
NTE_KEYSET_NOT_DEF | Ключевой контейнер, соответствующий pszContainer, не существует.
NTE_NO_MEMORY | Криптопровайдер во время операции исчерпал память.
NTE_TOKEN_KEYSET_STORAGE_FULL | Недостаточно места на носителе для сохранения информации.
NTE_SILENT_CONTEXT | Операция не может быть выполнена без пользовательского интерфейса.
SCARD_W_REMOVED_CARD | Носитель контейнера был удалён из считывателя.
SCARD_W_CANCELLED_BY_USER | Пользователь прервал операцию.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.
Файл описания: Прототип описан в файле wincspc.h.
Ядро ОС: При использовании в ядре ОС CPCAcquireContext допустимо вызывать только с флагами CRYPT_VERIFYCONTEXT|CRYPT_SILENT.

См. также

CPCReleaseContext() ,CPAcquireContext в MS CSP World Wide Web link ,CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link ,CryptSetProvParam в MS CryptoAPI 2.0 World Wide Web link


CPCReleaseContext

Функция CPCReleaseContext() используется для удаления дескриптора криптопровайдера, созданного CPCAcquireContext().

DWORD CPCAPI CPCReleaseContext(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  DWORD dwFlags
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
dwFlags
[in] Значения флагов. Параметр зарезервирован для будущего использования и должен быть нулевым.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
NTE_BAD_FLAGS | Параметр dwFlags имеет ненулевое значение.

Примечания

После того, как эта функция была вызвана, дескриптор hProv становится недействительным. Сессионные ключи и объекты функции хэширования, созданные с использованием дескриптора hProv, удаляются. Рекомендуется, чтобы приложение делало это заранее с использованием функций CPCDestroyKey() и CPCDestroyHash().

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CPCAcquireContext() ,CPReleaseContext в MS CSP World Wide Web link ,CryptReleaseContext в MS CryptoAPI 2.0 World Wide Web link


CPCGetProvParam

Функция CPCGetProvParam() получает параметры криптопровайдера.

DWORD CPCAPI CPCGetProvParam(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  DWORD dwParam,
  BYTE * pbData,
  DWORD * pdwDataLen,
  DWORD dwFlags
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
dwParam
[in] Значение, определяющее тип возвращаемых данных. В настоящее время определены следующие значения параметра dwParam.
Значение dwParam | Содержимое буфера pbData
PP_CONTAINER | Имя ключевого контейнера вида CONTAINER, если он имеет имя, в противном случае уникальное имя (см. PP_UNIQUE_CONTAINER). Строка, заканчивающаяся нулем, содержащая имя текущего ключевого контейнера. Подробнее см. Дополнительные параметры и определения .
PP_UNIQUE_CONTAINER | Уникальное имя ключевого контейнера, которое включает тип ключевого носителя и может иметь вид: MEDIA\FOLDER, MEDIA\UNIQUE\FOLDER или MEDIA\UNIQUE. Строка, заканчивающаяся нулем, содержащая имя текущего ключевого контейнера. Подробнее см. Дополнительные параметры и определения .
PP_ENUMALGS | Поддерживаемые алгоритмы. Подробнее см. CryptGetProvParam в MS CryptoAPI 2.0 World Wide Web link .
PP_ENUMALGS_EX | Поддерживаемые алгоритмы. Подробнее см. CryptGetProvParam в MS CryptoAPI 2.0 World Wide Web link .
PP_ENUMCONTAINERS | Имя одного из ключевых контейнеров, которые могут быть использованы криптопровайдером, возвращаемое в форме строки, заканчивающейся нулем. Прикладные программы могут вызывать функцию с данным параметром последовательно для перечисления всех ключевых контейнеров, поддерживаемых криптопровайдером. Эта функция не является многопоточной, и поэтому при использовании ее в многопоточном контексте есть вероятность, что не все поддерживаемые ключевые контейнеры будут перечислены.
PP_PROVTYPE | Тип криптопровайдера. Возвращается в виде переменной типа DWORD.
PP_IMPTYPE Тип реализации криптопровайдера. Возвращается в виде переменной типа DWORD. В настоящее время определены следующие типы реализации:
  • CRYPT_IMPL_HARDWARE
  • CRYPT_IMPL_SOFTWARE
  • CRYPT_IMPL_MIXED
  • CRYPT_IMPL_UNKNOWN
PP_HANDLE_COUNT | Количество используемых хэндлов. Должен быть установлен параметр dwFlags. При значении dwFlags = 0 - текущее количество. При значении dwFlags = 1 - максимальное. Возвращается в виде переменной типа DWORD.
PP_NAME | Имя провайдера в форме строки, заканчивающейся нулем. Это имя соответствует "CSP Name", которое программа setup установила в Windows® Registry.
PP_VERSION | Версия криптопровайдера. Возвращается в виде переменной типа DWORD. Например, версия 1.0 представляется как 0x00000100.
PP_VERSION_EX | Возвращает версию ядра криптопровайдера в виде структуры PROV_PP_VERSION_EX .
PP_KEYSPEC | Тип ключа (всегда либо AT_KEYEXCHANGE, либо AT_SIGNATURE, либо AT_UECSYMMETRICKEY). Возвращается в виде переменной типа DWORD.
PP_KEYX_KEYSIZE_INC | Размер модуля открытого ключа обмена AT_KEYEXCHANGE. Возвращается в виде переменной типа DWORD. Размер модуля ключа равен 512 (для ГОСТ Р 34.10-2001).
PP_SIG_KEYSIZE_INC | Размер модуля открытого ключа ЭП AT_SIGNATURE. Возвращается в виде переменной типа DWORD. Размер модуля ключа равен 512 (для ГОСТ Р 34.10-2001).
PP_KEYSET_SEC_DESCR | Возвращает дескриптор безопасности раздела реестра Windows, где хранятся ключи пользователя.
PP_KEYSET_TYPE | Определяет, является ли hProv контекстом ключа компьютера или пользователя. Возвращает DWORD со значением CRYPT_MACHINE_KEYSET, если этот флаг был передан в CPCAcquireContext(), или 0 в противном случае.
PP_KEYSTORAGE | Возвращает DWORD со значением CRYPT_SEC_DESCR.
PP_ENUMOIDS_EX | Поддерживаемые идентификаторы криптографических параметров алгоритмов. Перечисляются строковые величины - OID криптографических параметров алгоритмов.
PP_HASHOID | OID текущих параметров алгоритма функции хэширования.
PP_SIGNATUREOID | OID текущих параметров алгоритма подписи в зависимости от типа провайдера.
PP_DHOID | OID текущих параметров алгоритма Диффи-Хеллмана в зависимости от типа провайдера..
PP_CIPHEROID | OID текущих параметров алгоритма шифрования.
PP_CHECKPUBLIC | Передаёт в pbData значение флага проверки открытого ключа.
PP_RANDOM | Возвращает в pbData последовательность случайных чисел для установки программного ДСЧ криптопровайдера уровня ядра ОС. Если контекст криптопровайдера hProv открыт в режиме CRYPT_VERIFYCONTEXT, то предварительно будут получены случайные числа с физического или клавиатурного ДСЧ. См. описание параметра PP_USE_HARDWARE_RNG CPCSetProvParam().
PP_ENUM_HASHOID | Получает перечень идентификаторов криптографических объектов, связанных с функцией хэширования.
PP_ENUM_CIPHEROID | Получает перечень идентификаторов криптографических объектов, связанных с функцией шифрования.
PP_ENUM_SIGNATUREOID | Получает перечень идентификаторов криптографических объектов, связанных с функцией цифровой подписи, в зависимости от типа провайдера.
PP_ENUM_DHOID | Получает перечень идентификаторов криптографических объектов, связанных с алгоритмом Диффи-Хеллмана, в зависимости от типа провайдера.
PP_HCRYPTPROV | Загружает контейнер в память и возвращает DWORD идентифицирующий контейнер.
PP_SELECT_CONTAINER | Выводит диалоговое окно выбора контейнера и возвращает имя выбраного пользователем контейнера. Если dwFlags & CRYPT_FQCN, то имя контейнера возвращается в формате FQCN (см. PP_FQCN). Имя контейнера возвращается в текущей кодировке. Возвращаемая строка заканчивается нулем.
PP_FQCN | Возвращает FQCN (Fully Qualified Container Name) контейнера: \\.\<Reader>\<Name>, где <Reader> имя считывателя, на котором находится контейнер, <Name> имя контейнера в текущей кодировке. Возвращаемая строка заканчивается нулем.
PP_ENUMREADERS | Информация об одном из считывателей ключевых контейнеров, которые могут быть использованы криптопровайдером. Если dwFlags не содержит специальных значений, то в виде сериализованной псевдоструктуры CRYPT_ENUMREADER_INFO . Если dwFlags & CRYPT_MEDIA, то в виде сериализованной псевдоструктуры CRYPT_ENUMREADER_INFO_MEDIA . Прикладные программы могут вызывать функцию с данным параметром последовательно для перечисления всех считывателей, поддерживаемых криптопровайдером. Эта функция не является многопоточной, и поэтому при использовании ее в многопоточном контексте есть вероятность, что не все поддерживаемые считыватели будут перечислены.
PP_INFO | Вовращает структуру, содержащую значение таймера криптографического модуля, для недрайвера дополнительно содержит количество ДСРФ, свободное место на файловой системе /var, количество попыток выпусть ключ УЛ, количество успешных смен карт канала "К", количество карт канала выпущенных при последней смене, количество операций подписи
PP_PIN_INFO | Возвращает структуру пароля для текущего контейнера в виде структуры CRYPT_PIN_INFO
PP_PASSWD_TERM | Получает термин пароль ("пароль" / "pin-code") для текущего носителя. Возвращаемое значение содержит строку текущей кодировке заканчивающуюся нулем.
PP_SAME_MEDIA | Провека наличия носителя, соответствующего данному контейнеру, в считывателе. Возвращает TRUE, если носитель есть. FALSE и код ошибки SCARD_W_REMOVED_CARD, если отсутствует. Буфер pbData не используется.
PP_VERSION_TIMESTAMP | Получение даты и времени завершения компиляции в формате "day month year" "hh:mm:ss".
PP_SECURITY_LEVEL | Возвращает DWORD уровня сертификации данного криптографического модуля KC1: 1, KC2: 2, KC3: 3, KB1: 4, KB2: 5, KA1: 6
PP_FAST_CODE_FLAGS

Параметр предназначен для определения, какой код - быстрый или медленный - используется в провайдере на компьютерах, оснащенных процессором Intel Pentium 4. В pbData возвращается DWORD с флагами CSP_FAST_CODE_*. Параметр dwFlags должен содержать хотя бы один из флагов, указанных ниже.

Флаги для определения списка проверяемых функций.
CRYPT_FAST_CODE_ALL_KERNEL_FUNCTIONS - запрос кода функций провайдера уровня ядра ОС.
CRYPT_FAST_CODE_ALL_USER_FUNCTIONS - запрос кода функций провайдера уровня пользователя.
CRYPT_FAST_CODE_ALL_FUNCTIONS - запрос кода всех функций провайдера.
CRYPT_FAST_CODE_GET_SETFN - запроса результата работы функции определения процессора.

PP_ENUM_CONTAINER_EXTENSION | Имя одного из расширений ключевого контейнера, возвращаемое в форме структуры CONTAINER_EXTENSION. Прикладные программы могут вызывать функцию с данным параметром последовательно для перечисления всех расширений ключевого контейнера. Эта функция не является многопоточной, и поэтому при использовании ее в многопоточном контексте есть вероятность, что не все поддерживаемые считыватели будут перечислены.
PP_SELFTEST | [TODO:XX] Документация предварительная. [TODO:XX] Вызывает функцию самотестирования и контроля целостности. Для dwFlags равного нулю, тестируется оконечное СКЗИ. Результат возвращается в виде структуры PROV_PP_SELFTEST . При установке флага CP_CRYPT_SET_TESTER_STATUS устанавливается статус самотестирования. При установке флага CP_CRYPT_SELFTEST_FORCE_FAIL форсируется ошибка. При установке флага CP_CRYPT_SELFTEST_FORCE_SUCCESS форсируется успех.
PP_LICENSE | Возвращает серийный номер клиентской лицензии на CSP. Если лицензия не установлена или не действительна, функция возвращает FALSE. Серийный номер возвращается в виде строки символов типа char, заканчивающейся нулём. Возвращаемый серийный номер не содержит разделителей.
PP_EXCHANGE_KEY_FP | Возвращает первые 8 байт открытого ключа обмена. Если в контейнере нет ключа обмена, функция возвращает FALSE.
PP_SIGNATURE_KEY_FP | Возвращает первые 8 байт ключа проверки подписи. Если в контейнере нет ключа подписи, функция возвращает FALSE.
PP_CREATE_THREAD_CSP | Инициализирует структуру HCRYPTMODULE, предназначенную для работы в многопоточном режиме, в предварительно выделенной пользователем памяти, указатель на которую передан в pbData.
pbData
[out] Указатель на буфер, содержащий данные параметра. Функция копирует соответствующие параметру данные в буфер. Формат этих данных зависит от значения dwParam. Если аргумент функции - NULL, то данные не копируются. Требуемый размер буфера в байтах возвращается в pdwDataLen. Подробнее см. Возвращение данных неопределенной длины. Как отмечено в CryptGetProvParam в MS CryptoAPI 2.0 World Wide Web link , когда читается один из параметров перечисления, возвращенное в pdwDataLen значение будет равно размеру самого большого элемента в списке перечисления.
pdwDataLen
[in/out] Указатель на буфер, содержащий длину данных параметра. При вызове функции указанный аргумент содержит размер передаваемого буфера pbData в байтах. После возврата из неё pbData содержит число байтов данных параметра, скопированных в буфер pbData. Если буфер, соответствующий pbData, недостаточно велик, чтобы в него копировать запрошенные данные, через функцию GetLastError будет возвращен код ошибки ERROR_MORE_DATA. В этом случае требуемый размер буфера возвращается в pdwDataLen. Если эта функция завершается с кодом ошибки, отличным от ERROR_MORE_DATA, в этом аргументе возвращается ноль.
dwFlags
[in] Значения флагов. В настоящее время определены следующие значения флагов:
Значение dwFlags | Описание
CRYPT_FIRST | Используется совместно с параметром перечисления (например, PP_ENUMALGS, PP_ENUMALGS_EX или PP_ENUMCONTAINERS). При использовании этого флага возвращается первый элемент в списке перечисления, в противном случае возвращается следующий элемент в списке. Если флаг используется совместно с параметром, не являющимся параметром перечисления, то возвращается код ошибки NTE_BAD_FLAGS.
CRYPT_UNIQUE | Используется совместно с параметром PP_ENUMCONTAINERS. При использовании этого флага первыми по приоритету перед обычными именами возвращаются уникальные имена контейнеров. Если под уникальный номер выделено достаточно памяти, после уникального номера копируется обычное имя контейнера.
CRYPT_FQCN | Используется совместно с параметром PP_ENUMCONTAINERS, PP_SELECT_CONTAINER. При использовании этого флага имя контейнера возвращается в формате FQCN (см. PP_FQCN). Имя контейнера возвращается в текущей кодировке. Возвращаемая строка заканчивается нулем.
SECURITY_INFORMATION Если dwParam установлен в PP_KEYSET_SEC_DESCR, будет возвращен дескриптор безопасности раздела реестра, содержащего ключевой контейнер. В этом случае dwFlags используется, чтобы передать битовые флаги, объединяемые поразрядной операцией OR. Указатель на дескриптор безопасности возвращается в аргументе pbData, длина дескриптора безопасности возвращается в аргументе pcbData. Для получения дополнительной информации, см. RegGetKeySecurity и RegSetKeySecurity. Следующий список содержит определенные битовые маски, используемые для возврата требуемой информации.
  • OWNER_SECURITY_INFORMATION - Указывает идентификатор владельца упомянутого объекта.
  • GROUP_SECURITY_INFORMATION - Указывает идентификатор первичный группы упомянутого объекта.
  • DACL_SECURITY_INFORMATION - Указывает идентификатор дискреционного ACL упомянутого объекта.
  • SACL_SECURITY_INFORMATION - Указывает идентификатор системного ACL упомянутого объекта.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
ERROR_MORE_DATA | Размер буфера pbData недостаточен для копирования затребованных данных.
ERROR_NO_MORE_ITEMS | Достигнут конец списка перечисления. Данные в буфере pbData непригодны. Данный тип ошибки может возвращаться, только если dwParam имеет значение PP_ENUMALGS, PP_ENUMALGS_EX, PP_ENUMCONTAINERS, PP_ENUMOIDS_EX, PP_ENUM_HASHOID, PP_ENUM_CIPHEROID, PP_ENUM_SIGNATUREOID, PP_ENUM_DHOID или PP_ENUMREADERS.
NTE_BAD_FLAGS | Параметр dwFlags имеет некорректное значение.
NTE_BAD_TYPE | dwParam определяет неизвестный параметр.
SCARD_W_CANCELLED_BY_USER | Пользователь прервал операцию нажатием клавиши Cancel.
SCARD_W_WRONG_CHV | Пользователь ввёл неправильный пароль или пароль, установленный функцией SetProvParam, неправильный.
SCARD_E_INVALID_CHV | Пользователь ввёл пароль с нарушением формата или пароль, установленный функцией SetProvParam, имеет неправильный формат. Например, пароль имеет недопустимую длину или содержит недопустимые символы.
SCARD_W_CHV_BLOCKED | Ввод Pin-кода был заблокирован смарт-картой, т.к. исчерпалось количество попыток, разрешенное картой для ввода.
NTE_SILENT_CONTEXT | Операция не может быть выполнена без пользовательского интерфейса.
SCARD_W_REMOVED_CARD | Носитель контейнера был удален из считывателя.
NTE_BAD_SIGNATURE | Встроенный тест и/или контроль целостности СКЗИ выдал ошибку. Результаты находятся по адресу pbData, в виде структуры PROV_PP_SELFTEST .

Примечания

При указании параметра PP_SIGNATUREOID или PP_DHOID выбирается параметр, соответствующий типу провайдера. При указании параметра PP_ENUM_SIGNATUREOID или PP_ENUM_DHOID выбор соответствующего перечня идентификаторов производится аналогично.

PP_CIPHEROID для PROV_GOST_2001_DH по умолчанию равен "1.2.643.2.2.31.1", вариант "Верба-О"; для PROV_GOST_2012_256 или PROV_GOST_2012_512 равен "1.2.643.7.1.2.5.1.1", вариант ТК26 Z.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CPCAcquireContext() ,CPCSetProvParam() ,CPGetProvParam в MS CSP World Wide Web link ,CryptGetProvParam в MS CryptoAPI 2.0 World Wide Web link


CPCSetProvParam

Функция CPCSetProvParam() устанавливает параметры криптопровайдера.

DWORD CPCAPI CPCSetProvParam(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  DWORD dwParam,
  BYTE * pbData,
  DWORD dwFlags
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
dwParam
[in] Аргумент, принимающий следующие значения:
Значение dwParam | Содержимое буфера pbData
PP_KEYSET_SEC_DESCR | Устанавливает дескриптор безопасности раздела реестра Windows, где хранятся ключи пользователя. Значение дескриптора передаётся в pbData.
PP_HASHOID | Устанавливает идентификатор алгоритма функции хэширования.
PP_CIPHEROID | Устанавливает идентификатор алгоритма шифрования. </tr
PP_SIGNATUREOID | Устанавливает идентификатор алгоритма подписи в зависимости от типа провайдера.
PP_DHOID | Устанавливает идентификатор алгоритма Диффи-Хеллмана в зависимости от типа провайдера.
PP_KEYEXCHANGE_PIN Задаёт пароль (PIN) для доступа к ключам AT_SIGNATURE и AT_KEYEXCHANGE. Если пароль не задан этой функцией или задан этой функцией неверно, то он запрашивается у пользователя посредством UI перед первым обращением к носителю (если не был установлен флаг CRYPT_SILENT, см. CPCAcquireContext()). Если pbData - NULL, то существующий пароль для этого контейнера забывается и для доступа к ключу потребуется повторный ввод пароля.

В "КриптоПро CSP 4.0" используется единый пароль (PIN) для доступа к ключам AT_SIGNATURE и AT_KEYEXCHANGE. Параметры PP_KEYEXCHANGE_PIN и PP_SIGNATURE_PIN эквивалентны.
PP_SIGNATURE_PIN Задаёт пароль (PIN) для доступа к ключам AT_SIGNATURE и AT_KEYEXCHANGE. Если пароль не задан этой функцией или задан этой функцией неверно, то он запрашивается у пользователя посредством UI перед первым обращением к носителю (если не был установлен флаг CRYPT_SILENT, см. CPCAcquireContext()). Если pbData - NULL, то запомненный ранее пароль для этого контейнера забывается и для доступа к ключу потребуется повторный ввод пароля.

В "КриптоПро CSP 4.0" используется единый пароль (PIN) для доступа к ключам AT_SIGNATURE и AT_KEYEXCHANGE. Параметры PP_KEYEXCHANGE_PIN и PP_SIGNATURE_PIN эквивалентны.
PP_CHANGE_PIN | Задаёт новый пароль для контейнера hProv.
PP_SET_PIN | Устанавливает пароль на контейнер hProv в случае зашифрования его на другом контейнере или на нескольких контейнерах для схемы n из k. Этот пароль будет использован при последующем открытии контейнера hProv на чтение. Если контейнер hProv был создан при помощи функции CPCAcquireContext() с флагом CRYPT_NEWKEYSET, то пароль, устанавливаемый на него, также будет установлен на доступ к ключу этого контейнера. Если функция CPCSetProvParam() не вызывалась, то при доступе к ключу выдается UI (если не был установлен флаг CRYPT_SILENT, см. CPCAcquireContext()). При открытии контейнера в SILENT-режиме возвращается ошибка.
PP_USE_HARDWARE_RNG

Инициирует добавление к ДСЧ контекста криптопровайдера hProv последовательности с физического ДСЧ. Для считывания последовательности используются callback-функции, заданные при инициализации провайдера в поле hardwareRNG структуры CPC_CONFIG (см. CPC_HARDWARE_RNG ). Таким образом, вызов CPCSetProvParam с данным аргументом необходимо делать на уровне прерываний, на котором эти callback-функции в состоянии корректно работать.

В исполнении KC2 без успешного обращения к этой функции невозможна генерация ключей.

PP_RANDOM | Устанавливает в pbData ключевой блоб типа SIMPLEBLOB (см. CRYPT_SIMPLEBLOB ), содержащий последовательность случайных чисел, необходимую для установки программного ДСЧ уровня ядра ОС. См. описание параметра PP_RANDOM функции CPCGetProvParam().
PP_CHECKPUBLIC | Получает из pbData значение флага проверки открытого ключа. Если значение pbData типа DWORD равно 1, при импорте открытого ключа проверяется его корректность, если 0, проверка производится, если флаг установлен по параметру PP_ADMIN_CHECKPUBLIC. Открытый ключ, соответствующий ГОСТ 34.10-2001, проверяется всегда.
PP_ADMIN_CHECKPUBLIC | Получает из pbData значение флага проверки открытого ключа и устанавливает его в реестр. Если значение установленного в реестре флага равно 1, при импорте открытого ключа проверяется его корректность независимо от установки пользователя по параметру PP_CHECKPUBLIC, если значение установленного в реестре флага равно 0, проверка производится в зависимости от установки по параметру PP_CHECKPUBLIC. Открытый ключ, соответствующий ГОСТ 34.10-2001, проверяется всегда.
PP_FAST_CODE_FUNCS | Параметр предназначен для управления подключением быстрых функций на на процессорах с архитектурой ia32/amd64. Применяется для установки функций захвата и освобождения регистров расширений MMX/SSE2/SSSE3/AVX. Определён только в KC1. В многопоточном окружении следует учитывать, что изменяет настройки всего СКЗИ (HCRYPTMODULE) и должна выполнятся, в общем случае, при том условии, что нет открытых контекстов ключей и/или ключей. В режиме ядра, при установке CPC_FAST_CODE_USER и нулевых указателях на функции захвата/освобождения FPU, они не изменяются. В pbData структура типа CPC_FAST_CODE .
PP_NK_SYNC | Производит запись одной из частей контейнера разделенного по схеме K из N. В качестве pbData должен быть передан DWORD полученный функцией GetProvParam с параметром PP_HCRYPTPROV. Функция используется для создания контейнера разделенного на части без выдачи окон.
PP_DELETE_KEYSET | Удаляет текущий контейнер с носителя. Функция используется для удаления контейнеров, требующих для очистки пароля, в SILENT режиме. Контейнер после успешного завершения данной операции больше не может быть использован ни в одной функции провайдера, исключая CPCReleaseContext (CryptReleaseContext).
PP_CONTAINER_EXTENSION | Устанавливает extension для контейнера. Если extension уже был задан в контейнере, то функция заменяет этот extension в контейнере. В качестве pbData должен быть передан extension в формате CERT_EXTENSION.
PP_CONTAINER_EXTENSION_DEL | Удаляет из контейнера extension, заданный строковым представлением OID.
PP_CONTAINER_DEFAULT | Устанавливает текущий контейнер - контейнером по умолчанию на текущем носителе.
pbData
[in] Указатель на буфер, содержащий данные параметра. Этот буфер при обращении к функции должен содержать данные, которые соответствуют типу параметра, помещённому в dwParam. Формат данных зависит от типа параметра.
dwFlags
[in] Значения флагов. Используются следующие значения флагов:
Значение dwFlags Описание
SECURITY_INFORMATION Флаг устанавливается, если dwParam установлен в дескриптор безопасности раздела реестра PP_KEYSET_SEC_DESCR,содержащего ключевой контейнер. Указатель на дескриптор безопасности передаётся в аргументе pbData, его длина передаётся в аргументе pcbData. Используются следующие битовые флаги:
  • OWNER_SECURITY_INFORMATION - Указывает идентификатор владельца объекта.
  • GROUP_SECURITY_INFORMATION - Указывает идентификатор первичный группы объекта.
  • DACL_SECURITY_INFORMATION - Указывает идентификатор дискреционного ACL объекта.
  • SACL_SECURITY_INFORMATION - Указывает идентификатор системного ACL объекта.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_DATA | Длина идентификатора главного ключа пользователя превышает максимально допустимую. Если функция вызывалась с PP_FAST_CODE_FUNCS, ошибка в заданном размере буфера для сохранения регистров.
NTE_BAD_FLAGS | Величина dwFlags имеет ненулевое значение.
NTE_BAD_TYPE | dwParam определяет неизвестный параметр.
NTE_KEYSET_ENTRY_BAD | Нарушение целостности ключей в ОЗУ.
NTE_FAIL | Ошибка при считывании данных из системного реестра.
SCARD_W_CANCELLED_BY_USER | Пользователь прервал операцию нажатием клавиши Cancel
SCARD_W_WRONG_CHV | Пользователь ввёл неправильный пароль или пароль, установленный функцией SetProvParam, неправильный
SCARD_E_INVALID_CHV | Пользователь ввёл пароль с нарушением формата или пароль, установленный функцией SetProvParam(), имеет неправильный формат. Например, пароль имеет недопустимую длину или содержит недопустимые символы.
SCARD_W_CHV_BLOCKED | Ввод Pin-кода был заблокирован смарт-картой, т.к. исчерпалось количество попыток разрешенное картой для ввода.
NTE_TOKEN_KEYSET_STORAGE_FULL | Недостаточно места на носителе для сохранения информации.
NTE_SILENT_CONTEXT | Операция не может быть выполнена без пользовательского интерфейса.
SCARD_W_REMOVED_CARD | Носитель контейнера был удален из считывателя

Примечания

При указании параметра PP_SIGNATUREOID или PP_DHOID выбирается параметр, соответствующий типу провайдера.

Устанавливаемые с помощью PP_DHOID/PP_SIGNATUREOID идентификаторы параметров закрытых ключей определяют данные параметры только для долговременных ключей и эфемерных ключей, тип которых соответствует типу провайдера. Для эфемерных ключей, тип которых не соответствует типу провайдера, идентификаторы параметров необходимо указывать явно с помощью функции CPCSetKeyParam().

См. также

CPCAcquireContext() ,CPCGetProvParam() ,CPSetProvParam в MS CSP World Wide Web link ,CryptSetProvParam в MS CryptoAPI 2.0 World Wide Web link


CPCCreateProvider

Функция CPCCreateProvider() используется для инициализации и настройки криптопровайдера, и для получения таблицы остальных его функций.

DWORD CPCAPI CPCCreateProvider(
  HCRYPTMODULE * phCSP,
  LPCPC_CONFIG pConfig
);

Аргументы

phCSP
[out] Адрес, по которому функция копирует указатель на таблицу функций криптопровайдера (CPC_FUNCTION_TABLE_ ).
pConfig
[in] Указатель на структуру CPC_CONFIG_ , содержащую настройки криптопровайдера.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_FAIL | Общая ошибка инициализации.
NTE_NO_MEMORY | Криптопровайдер во время операции исчерпал память.
NTE_PROVIDER_DLL_FAIL | Криптопровайдер неправильно установлен или переданная лицензия неверна.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.
Ядро ОС: При использовании в ядре ОС CPCAcquireContext допустимо вызывать только с флагами CRYPT_VERIFYCONTEXT|CRYPT_SILENT.

См. также

CPCDestroyProvider, CPCGetDefaultConfig


CPCDestroyProvider

Функция CPCDestroyProvider() используется для завершения работы с провайдером и освобождения всех ресурсов, занятых вызовом CPCCreateProvider().

DWORD CPCAPI CPCDestroyProvider(
  HCRYPTMODULE hCSP
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
NTE_FAIL | Общая ошибка.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CPCCreateProvider()


CPCInitMemoryLF

Функция создания безблокировочного менеджера памяти. Создает арену, которую можно использовать в настройках провайдера при его создании функцией CPCCreateProvider.

Данный менеджер памяти является реентерабельным, при полном отсутствии ждущих блокировок, и может быть использован на любом уровне прерываний. Он осуществляет распределение памяти из блока фиксированного размера, переданного при инициализации, и не захватывает дополнительной памяти.

DWORD CPCAPI CPCInitMemoryLF(
  LPCPC_MEMORY_ARENA * pArena,
  LPCPC_LFMM_CONFIG cfg
);

Аргументы

pArena
[out] Указатель, по которому будет возвращен адрес менеджера памяти (CPC_MEMORY_ARENA_).
cfg
[in] Указатель на структуру настроек безблокировочного менеджера памяти (имеют тип CPC_LFMM_CONFIG_)

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответсующий код ошибки (см. таблицу).
Коды возврата | Описание
NTE_NO_MEMORY | Криптопровайдер во время операции исчерпал память.

См. также

CPC_MEMORY_ARENA_, CPCCreateProvider


Структуры данных, используемые в режиме ядра ОС

Предназначены для взаимодействия с программами пользователя, непосредственно использующими "КриптоПро CSP 4.0" в режиме ядра ОС

  • Callback-функции, используемые в режиме ядра ОС
Структуры | Описание
_CPC_FAST_CODE | Настройки использования расширений процессора: MMX, SSE2, SSSE3, AVX.
CPC_FUNCTION_TABLE_ | Таблица функций провайдера уровня ядра ОС, возвращаемая функцией CPCCreateProvider. Указатель на неё (HCRYPTMODULE) передаётся в качестве первого параметра во все остальные функции провайдера уровня ядра ОС.
CPC_LOG_CONFIG_ | Структура настроек журнала.
CPC_HARDWARE_RNG_ | Структура настроек аппаратного датчика случайных чисел.
CPC_LOCK_FUNCS_ | Структура настроек блокировок с ожиданием.
CPC_TIME_FUNCS_ | Структура настроек работы со временем.
CPC_ALG_PARAMS_ | Структура настроек параметров алгоритмов.
CPC_INTERLOCKED_FUNCS_ | Структура настроек примитивов синхронизации. Используется только на процессорах ARM и sparc-v8 (32).
CPC_CONFIG_ | Структура инициализации и настройки провайдера уровня ядра ОС.
CPC_LFMM_CONFIG_ | Интерфейс безблокировочного (lock-free) менеджера памяти.
CPC_MEMORY_STATS_ | Структура статистики менеджера памяти.
CPC_MEMORY_ARENA_ | Структура менеджера памяти. Указатель на неё входит в структуру CPC_CONFIG_. Все операции с динамической памятью провайдер осуществляет с помощью данной структуры.


Callback-функции, используемые в режиме ядра ОС

Предназначены для взаимодействия с программами пользователя, непосредственно использующими "КриптоПро CSP 4.0" в режиме ядра ОС

Функции | Описание
CPC_print_str | Callback-функция для вывода сообщений.
CPC_get_thread_id | Callback-функция для получения идентификатора потока (процессора).
CPC_InitRWLock | Callback-функция для операции инициализации блокировки, предоставляеммой пользователем.
CPC_DestroyRWLock | Callback-функция для операции уничтожения блокировки, предоставляеммой пользователем.
CPC_WRLockRWLock | Callback-функция для операции установки эксклюзивной блокировки (блокировки на запись), предоставляеммой пользователем.
CPC_RDLockRWLock | Опциональная Callback-функция для операции установки разделяемой блокировки (блокировки на чтение), предоставляеммой пользователем.
CPC_UnlockRWLock | Callback-функция для операции снятия блокировки, предоставляеммой пользователем.
CPC_GetTimeOfDay | Callback-функция для определения текущего времени.
CPC_RDTSC | Callback-функция для определения текущего счетчика тактов процессора (TSC).
CPC_RandomGenerate | Callback-функция для обращения к аппаратному датчику случайных чисел.
CPC_RandomCleanup | Callback-функция для освобождения аппаратного датчика случайных чисел.
CPC_InterlockedExchangeAdd | Callback-функция для атомарной операции сложения (*dest = *dest + incr);.
CPC_InterlockedCASL | Callback-функция для атомарной операции условной замены четырёх байт. if (*dest != compare) return FALSE; *dest = xchg; return TRUE;.
CPC_InterlockedCASLL | Callback-функция для атомарной операции условной замены восьми байт. if (*dest != compare) return FALSE; *dest = xchg; return TRUE;.
CPC_AllocMemory | Callback-функция выделения памяти.
CPC_FreeMemory | Callback-функция освобождения памяти.
CPC_StatMemory | Callback-функция сбора статистики использования памяти.
CPC_ValidateMemory | Callback-функция проверки корректности состояния кучи.
CPC_DoneMemory | Callback-функция - деструктор кучи.
CPC_MemoryException | Callback-функция обработки исключений при выделении памяти.


CPC_print_str

Callback-функция для вывода сообщений.

void CPCAPI CPC_print_str(
  void * callback_arg,
  const TCHAR * str
);

Аргументы

callback_arg
[in] Параметр, переданный при регистрации callback-функции.
str
[in] Строка, которую нужно вывести. Не включает '\n'.


CPC_get_thread_id

Callback-функция для получения идентификатора потока (процессора).

unsigned long CPCAPI CPC_get_thread_id(
  void
);

Возвращаемые значения

При успешном завершении функция должна возвратить 0 (S_OK), или соответствующий код ошибки в противном случае.


CPC_InitRWLock

Callback-функция для операции инициализации блокировки, предоставляеммой пользователем.

DWORD CPCAPI CPC_InitRWLock(
  LPCPC_RWLOCK pSection,
  DWORD cbSection,
  LPVOID lpArg
);

Аргументы

pSection
[out] Адрес блокировки.
cbSection
[in] Размер блокировки в байтах.
lpArg
[in] Аргумент, переданный при регистрации Callback-функции.

Возвращаемые значения

При успешном завершении функция должна возвратить 0 (S_OK), или соответствующий код ошибки в противном случае.

См. также

CPC_LOCK_FUNCS_


CPC_DestroyRWLock

Callback-функция для операции уничтожения блокировки, предоставляеммой пользователем.

VOID CPCAPI CPC_DestroyRWLock(
  LPCPC_RWLOCK pSection
);

Аргументы

pSection
[in][out] Адрес блокировки.

См. также

CPC_LOCK_FUNCS_


CPC_WRLockRWLock

Callback-функция для операции установки эксклюзивной блокировки (блокировки на запись), предоставляеммой пользователем.

VOID CPCAPI CPC_WRLockRWLock(
  LPCPC_RWLOCK pSection
);

Аргументы

pSection
[in][out] Адрес критической секции.

См. также

CPC_LOCK_FUNCS_


CPC_RDLockRWLock

Опциональная Callback-функция для операции установки разделяемой блокировки (блокировки на чтение), предоставляеммой пользователем.

VOID CPCAPI CPC_RDLockRWLock(
  LPCPC_RWLOCK pSection
);

Аргументы

pSection
[in][out] Адрес критической секции.

Примечания

Если пользователь её не задаёт, то она заменяется #CPC_WRLockRWLock, в этом случае все операции в одном контексте исполняются последовательно. Операции в разных контекстах могут выполнятся паралельно.

См. также

CPC_LOCK_FUNCS_


CPC_UnlockRWLock

Callback-функция для операции снятия блокировки, предоставляеммой пользователем.

VOID CPCAPI CPC_UnlockRWLock(
  LPCPC_RWLOCK pSection
);

Аргументы

pSection
[in][out] Адрес блокировки.

См. также

CPC_LOCK_FUNCS_


CPC_GetTimeOfDay

Callback-функция для определения текущего времени.

DWORD CPCAPI CPC_GetTimeOfDay(
  CPC_timeval * pTV,
  LPVOID lpArg
);

Аргументы

pTV
[out] Адрес переменной, в которую должно быть записано текущее время (UTC в мкс,

См. также

CPC_timeval).

Аргументы

lpArg
[in] Аргумент, переданный при регистрации Callback-функции.

Возвращаемые значения

При успешном завершении функция должна возвратить 0 (S_OK), или соответствующий код ошибки в противном случае.

См. также

CPC_TIME_FUNCS_


CPC_RDTSC

Callback-функция для определения текущего счетчика тактов процессора (TSC).

DWORD CPCAPI CPC_RDTSC(
  ULONGLONG * pTSC,
  LPVOID lpArg
);

Аргументы

pTSC
[out] Адрес переменной, в которую будет записано текущее значение счетчика.
lpArg
[in] Аргумент, переданный при регистрации Callback-функции.

Возвращаемые значения

При успешном завершении функция должна возвратить 0 (S_OK), или соответствующий код ошибки в противном случае.

См. также

CPC_TIME_FUNCS_


CPC_RandomGenerate

Callback-функция для обращения к аппаратному датчику случайных чисел.

DWORD CPCAPI CPC_RandomGenerate(
  LPVOID lpCtx,
  DWORD length,
  PBYTE data
);

Аргументы

lpCtx
[in] Указатель на контекст.
length
[in] Количество байт, которые требуется выработать.
data
[out] Буфер, в который будут записаны случайные числа.

Возвращаемые значения

При успешном завершении функция должна возвратить 0 (S_OK), или соответствующий код ошибки в противном случае.

См. также

CPC_HARDWARE_RNG_


CPC_RandomCleanup

Callback-функция для освобождения аппаратного датчика случайных чисел.

VOID CPCAPI CPC_RandomCleanup(
  LPVOID lpCtx
);

Аргументы

lpCtx
[in] Указатель на контекст.

См. также

CPC_HARDWARE_RNG_


CPC_InterlockedExchangeAdd

Callback-функция для атомарной операции сложения (*dest = *dest + incr);.

LONG CPCAPI CPC_InterlockedExchangeAdd(
  LONG volatile * dest,
  LONG incr
);

Аргументы

dest
[in][out] Адрес первого слагаемого, оно же приёмник.
incr
[in] Второе слагаемое.

См. также

CPC_INTERLOCKED_FUNCS_


CPC_InterlockedCASL

Callback-функция для атомарной операции условной замены четырёх байт. if (*dest != compare) return FALSE; *dest = xchg; return TRUE;.

BOOL CPCAPI CPC_InterlockedCASL(
  LONG volatile * dest,
  LONG xchg,
  LONG compare
);

Аргументы

dest
[in][out] Адрес приёмника.
xchg
[in] Новое значение.
compare
[in] Старое значение.

Возвращаемые значения

Должна возвратить TRUE, если удалось осуществить операцию.

См. также

CPC_INTERLOCKED_FUNCS_


CPC_InterlockedCASLL

Callback-функция для атомарной операции условной замены восьми байт. if (*dest != compare) return FALSE; *dest = xchg; return TRUE;.

BOOL CPCAPI CPC_InterlockedCASLL(
  LONGLONG volatile * dest,
  LONGLONG xchg,
  LONGLONG compare
);

Аргументы

dest
[in][out] Адрес приёмника.
xchg
[in] Новое значение.
compare
[in] Старое значение.

Возвращаемые значения

Должна возвратить TRUE, если удалось осуществить операцию.

См. также

CPC_INTERLOCKED_FUNCS_


CPC_AllocMemory

Callback-функция выделения памяти.

DWORD CPCAPI CPC_AllocMemory(
  LPCPC_MEMORY_ARENA pArena,
  CPC_SIZE_T dwSize,
  DWORD dwMemPoolId,
  DWORD dwThreadId,
  LPVOID * pRes
);

Аргументы

pArena
[in] Указатель на структуру менеджера памяти.
dwSize
[in] Размер выделяемого блока (в байтах).
dwMemPoolId
[in] Идентификатор раздела кучи (MP_WORK, MP_PRIME, и т.д.).
dwThreadId
[in] Идентификатор потока или процессора.
pRes
[out] Указатель на переменную, в которую будет помещен результат.

Возвращаемые значения

При успешном завершении функция должна возвратить 0 (S_OK), или соответствующий код ошибки в противном случае.

См. также

CPC_MEMORY_ARENA_


CPC_FreeMemory

Callback-функция освобождения памяти.

DWORD CPCAPI CPC_FreeMemory(
  LPCPC_MEMORY_ARENA pArena,
  VOID * pMem,
  DWORD dwMemPoolId
);

Аргументы

pArena
[in] Указатель на структуру менеджера памяти.
pMem
[in] Указатель на освобождаемый блок.
dwMemPoolId
[in] Идентификатор раздела кучи (MP_WORK, MP_PRIME, и т.д.).

Возвращаемые значения

При успешном завершении функция должна возвратить 0 (S_OK), или соответствующий код ошибки в противном случае.

См. также

CPC_MEMORY_ARENA_


CPC_StatMemory

Callback-функция сбора статистики использования памяти.

VOID CPCAPI CPC_StatMemory(
  LPCPC_MEMORY_ARENA pArena,
  LPCPC_MEMORY_STATS pStats,
  DWORD dwMemPoolId
);

Аргументы

pArena
[out] Указатель на структуру менеджера памяти.
pStats
[in] Указатель на структуру CPC_MEMORY_STATS_, в которую будет помещен результат.
dwMemPoolId
[in] Идентификатор раздела кучи (MP_WORK, MP_PRIME, и т.д.).

См. также

CPC_MEMORY_ARENA_


CPC_ValidateMemory

Callback-функция проверки корректности состояния кучи.

VOID CPCAPI CPC_ValidateMemory(
  LPCPC_MEMORY_ARENA pArena
);

Аргументы

pArena
[in] Указатель на структуру менеджера памяти.

См. также

CPC_MEMORY_ARENA_


CPC_DoneMemory

Callback-функция - деструктор кучи.

VOID CPCAPI CPC_DoneMemory(
  LPCPC_MEMORY_ARENA pArena
);

Аргументы

pArena
[in] Указатель на структуру менеджера памяти.

См. также

CPC_MEMORY_ARENA_


CPC_MemoryException

Callback-функция обработки исключений при выделении памяти.

VOID CPCAPI CPC_MemoryException(
  LPCPC_MEMORY_ARENA pArena,
  VOID * arg
);

Аргументы

pArena
[in] Указатель на структуру менеджера памяти.
arg
[in] Аргумент, переданный при регистрации Callback-функции.

См. также

CPC_MEMORY_ARENA_


_CPC_FAST_CODE

Настройки использования расширений процессора: MMX, SSE2, SSSE3, AVX.

На процессорах Intel Pentium 4 и новее можно достичь ускорения алгоритмов шифрования и хэширования за счёт использования инструкций расширений MMX, SSE2, SSSE3, AVX. Настройка захвата SSE2 осуществляется с помощью данной структуры.

Криптографические функции, использующие расширения, сведены в следующие наборы:

Идентификатор набора | Группа
CSP_OPERATION_CIPHER1 | Неспараллеливаемые функции шифрования по ГОСТ 28147-89. Для них необходимо только командное расширение MMX.
CSP_OPERATION_CIPHER2 | Спараллеленные функции шифрования по ГОСТ 28147-89. Для них необходимо только командное расширение MMX, возможно использование SSSE3 и AVX.
CSP_OPERATION_IMIT | Функция выработки имитовставки по ГОСТ 28147-89. Для нее необходимо только командное расширение MMX.
CSP_OPERATION_HASH | Функции хэширования по ГОСТ Р 34.11-94. Для них необходимы командные расширения MMX и SSE2.
CSP_OPERATION_MULT | Функция умножения в поле по модулю P (Применяется в протоколах подписи и Диффи-Хеллмана). Для неё необходимы командные расширения MMX и SSE2.
CSP_FAST_CODE_DISABLE_SSSE3 | Запрет использования командного расширения SSSE3.
CSP_FAST_CODE_DISABLE_AVX | Запрет использования командного расширения AVX.
CSP_FAST_CODE_RT_TS | Захват FPU только на время операции, применяется в случае если для захвата используется TS-бит (Solaris, Linux).
Совокупность выборов универсальных или использующих командные расширения наборов функций будем называть сочетанием наборов. Любое сочетание наборов кодируется в одном двойном машинном слове, как логическая сумма идентификаторов наборов функций MMX и SSE.

В связи с большим разнообразием аппаратных платформ на базе процессоров архитектуры x86 и эмуляций x86 на архитектурах x64 и IA64, нет возможности заранее определить, какой из наборов функций в группах будет работать быстрее на конкретном процессоре, с конкретной частотой шины, скоростью памяти и т.п.

Настроить провайдер на использование наиболее быстрого сочетания наборов можно:

  • с помощью вызова SetProvParam (PP_FAST_CODE_FUNCS), в который передаётся данная структура
  • на уровне CPC, при инициализации криптографического модуля, путём передачи данной структуры в инициализатор провайдера
  • при использовании криптопровайдера в пользовательском режиме, путём установки маски оптимального набора функций в реестр в '\Crypto Pro\Cryptography\CurrentVersion\Parameters\MMXFuncs' или на Unix командой: "cpconfig -ini '\\config\\Parameters' -add long MMXFuncs значение_маски", куда надо вписать значение соответствующее полю UsedMask из структуры.
  • c помощью команды 'csptest -speed -type ALL -mode REG'. Такой вызов проведёт короткий тест и запишет оптимальные параметры в указанный выше ключ реестра.

    • У провайдера есть три режима использования функций MMX/SSE/SSSE3/AVX:

  • Некое стандартное сочетание, считающиеся наиболее производительным.
  • Сочетание, состоящее только из наборов универсальных функций.
  • Сочетание, устанавливаемое пользователем с помощью функции SetProvParam.

    • Первое из них при работе через уровни Crypt и CP устанавливаются из реестра, или, если реестр недоступен или параметр не определён, как некоторое стандартное сочетание, задаваемое провайдером для данной системы. При работе на уровне CPC первое сочетание передаётся пользователем при инициализации провайдера, или запрашивается установка стандартного для провайдера сочетания.

    При установке некоторого выбираемого пользователем сочетания наборов возможен выбор используемого набора расширений: MMX, SSE2, SSSE3 или AVX. При установке нового сочетания наборов провайдер в любом случае проверит, возможно ли на данном процессоре использование таких наборов функций MMX/SSE/SSSE3/AVX, и, если возможность есть, установит наборы. В режиме ядра, кроме того, перед вызовом каждой функции, использующей MMX/SSE/SSSE3/AVX, будет осуществлён вызов callback'а захвата FPU, и специализированный код будет использоваться только в случае успешного захвата, после чего будет вызван callback функции освобождения FPU. Если захват не удался, будет выполняться универсальный код функции.

    typedef struct _CPC_FAST_CODE {
      DWORD UsesFunctions;
      CPC_Kernel_Fpu_Begin_Callback * cp_kernel_fpu_begin;
      CPC_Kernel_Fpu_End_Callback * cp_kernel_fpu_end;
      DWORD Kernel_Buf_Size;
      DWORD UsedMask;
} CPC_FAST_CODE;

    Члены

    UsesFunctions
    Обязательный параметр, может быть равен CPC_FAST_CODE_DEFAULT, CPC_FAST_CODE_NO, CPC_FAST_CODE_USER.
    Возможные значения: Интерпретация:
    CPC_FAST_CODE_DEFAULT | Использовать сочетание наборов по умолчанию.
    CPC_FAST_CODE_NO | Использовать сочетание наборов универсальных функций.
    CPC_FAST_CODE_USER | Использовать сочетание наборов функций, задаваемое параметром UsedMask.
    cp_kernel_fpu_begin
    Указатель на функцию захвата FPU. Применяется в режиме ядра. Указывает на функцию захвата FPU, которую будут вызывать функции, использующие расширения MMX/SSE/SSSE3/AVX. Устанавливается только при UsesFunctions == CPC_FAST_CODE_USER. Если равно нулю при использовании в CPCSetProvParam(), сохраняется предыдущее значение. См. CPC_Kernel_Fpu_Begin_Callback
    cp_kernel_fpu_end
    Указатель на функцию освобождения FPU. Применяется в режиме ядра. Указывает на функцию освобождения FPU. Используется только при UsesFunctions == CPC_FAST_CODE_USER. Если равно нулю при использовании в CPCSetProvParam(), сохраняется предыдущее значение. См. CPC_Kernel_Fpu_End_Callback
    Kernel_Buf_Size
    Размер не выровненного буфера, который будет передаваться в функции захвата и освобождения FPU для сохранения регистров. Используется только при UsesFunctions == CPC_FAST_CODE_USER. Значение не может превышать 2048. См. CPC_Kernel_Fpu_Begin_Callback , CPC_Kernel_Fpu_End_Callback
    UsedMask
    Маска, задающая сочетание наборов функций. Является логической суммой идентификаторов наборов функций, использующих командные расширения, которые следует вызывать в криптопровайдере (см. выше). В пользовательском режиме в ней передаются любые возможные сочетания всех пяти наборов, в режиме ядра - всех, кроме набора умножения по модулю P.

    Примечания

    Важно, что бы другие функции определяемые пользователем в конфигурации CPC_CONFIG_ сохраняли возможность использования расширений процессора текущим контекстом исполнения (начиная, со сборки 3.6.7747, определяемые пользователем функции блокировок с ожиданием CPC_LOCK_FUNCS_ не вызываются во время использования расширений процессора).

    Поддержка командных расширений по умолчанию на уровне пользователя согласно возможностям процессора и ОС.

    Поддержка командных расширений по умолчанию на уровне ядра ОС:

    Ядро ОС | Поддержка
Windows 7/2008R2 SP1 | до AVX
Windows иные | до SSSE3
Linux с версии ядра 2.6.30 | до AVX
Linux ранее | до SSSE3
FreeBSD с версии 8.2 | до AVX
FreeBSD ранее | базовый код без использования FPU/MMX/SSE2/SSSE3/AVX
Solaris 10/11 amd64 | до SSSE3
Solaris 10/11 ia32 | базовый код без использования FPU/MMX/SSE2/SSSE3/AVX

    См. также

    CPC_CONFIG_


CPC_FUNCTION_TABLE_

Таблица функций провайдера уровня ядра ОС, возвращаемая функцией CPCCreateProvider. Указатель на неё (HCRYPTMODULE) передаётся в качестве первого параметра во все остальные функции провайдера уровня ядра ОС.

typedef struct CPC_FUNCTION_TABLE_ {
  CPCAcquireContext_t * AcquireContext;
  CPCReleaseContext_t * ReleaseContext;
  CPCGetProvParam_t * GetProvParam;
  CPCSetProvParam_t * SetProvParam;
  CPCGenKey_t * GenKey;
  CPCDestroyKey_t * DestroyKey;
  CPCCreateHash_t * CreateHash;
  CPCDestroyHash_t * DestroyHash;
  CPCEncrypt_t * Encrypt;
  CPCDecrypt_t * Decrypt;
  CPCDeriveKey_t * DeriveKey;
  CPCDuplicateKey_t * DuplicateKey;
  CPCDuplicateHash_t * DuplicateHash;
  CPCExportKey_t * ExportKey;
  CPCGenRandom_t * GenRandom;
  CPCGetHashParam_t * GetHashParam;
  CPCGetKeyParam_t * GetKeyParam;
  CPCGetUserKey_t * GetUserKey;
  CPCHashData_t * HashData;
  CPCHashSessionKey_t * HashSessionKey;
  CPCImportKey_t * ImportKey;
  CPCSetHashParam_t * SetHashParam;
  CPCSetKeyParam_t * SetKeyParam;
  CPCSignHash_t * SignHash;
  CPCVerifySignature_t * VerifySignature;
  CPCDestroyProvider_t * DestroyProvider;
} CPC_FUNCTION_TABLE, *HCRYPTMODULE;

Члены

AcquireContext
Указатель на функцию CPCAcquireContext.
ReleaseContext
Указатель на функцию CPCReleaseContext.
GetProvParam
Указатель на функцию CPCGetProvParam.
SetProvParam
Указатель на функцию CPCSetProvParam.
GenKey
Указатель на функцию CPCGenKey.
DestroyKey
Указатель на функцию CPCDestroyKey.
CreateHash
Указатель на функцию CPCCreateHash.
DestroyHash
Указатель на функцию CPCDestroyHash.
Encrypt
Указатель на функцию CPCEncrypt.
Decrypt
Указатель на функцию CPCDecrypt.
DeriveKey
Указатель на функцию CPCDeriveKey.
DuplicateKey
Указатель на функцию CPCDuplicateKey.
DuplicateHash
Указатель на функцию CPCDuplicateHash.
ExportKey
Указатель на функцию CPCExportKey.
GenRandom
Указатель на функцию CPCGenRandom.
GetHashParam
Указатель на функцию CPCGetHashParam.
GetKeyParam
Указатель на функцию CPCGetKeyParam.
GetUserKey
Указатель на функцию CPCGetUserKey.
HashData
Указатель на функцию CPCHashData.
HashSessionKey
Указатель на функцию CPCHashSessionKey.
ImportKey
Указатель на функцию CPCImportKey.
SetHashParam
Указатель на функцию CPCSetHashParam.
SetKeyParam
Указатель на функцию CPCSetKeyParam.
SignHash
Указатель на функцию CPCSignHash.
VerifySignature
Указатель на функцию CPCVerifySignature.
DestroyProvider
Указатель на функцию CPCDestroyProvider.

См. также

CPCCreateProvider


CPC_LOG_CONFIG_

Структура настроек журнала.

typedef struct CPC_LOG_CONFIG_ {
  const TCHAR * name;
  unsigned level;
  unsigned format;
  CPC_print_str_Callback * dprint_str;
  CPC_print_str_Callback * eprint_str;
  CPC_print_str_Callback * cprint_str;
  CPC_print_str_Callback * elprint_str;
  CPC_get_thread_id_Callback * get_thread_id;
  LPVOID lpArg;
} CPC_LOG_CONFIG;

Члены

name
Формат сообщений: имя модуля, напр. TEXT("cpcsp").
level
Формат сообщений: разрешенные уровни сообщений (комбинация флагов DBType_).
format
Формат сообщений: формат печати сообщений (комбинация флагов SUPPORT_DBFMT*).
dprint_str
Callback-функция для выдачи отладочных сообщений. Имеет тип CPC_print_str.
eprint_str
Callback-функция для выдачи сообщений об ошибках. Имеет тип CPC_print_str.
cprint_str
Callback-функция для выдачи сообщений о критических ошибках. Имеет тип CPC_print_str.
elprint_str
get_thread_id
Callback-функция для получения идентификатора потока. Имеет тип CPC_get_thread_id.
lpArg
Аргумент для callback-ов dprint_str, eprint_str, cprint_str.

См. также

CPC_CONFIG_


CPC_HARDWARE_RNG_

Структура настроек аппаратного датчика случайных чисел.

typedef struct CPC_HARDWARE_RNG_ {
  CPC_RandomGenerate_Callback * random_generate;
  CPC_RandomCleanup_Callback * random_cleanup;
  LPVOID lpCtx;
} CPC_HARDWARE_RNG;

Члены

random_generate
Callback-функция для обращения к аппаратному датчику случайных чисел. Имеет тип CPC_RandomGenerate.
random_cleanup
Callback-функция для освобождения датчика случайных чисел. Имеет тип CPC_RandomCleanup.
lpCtx
Контекст датчика случайных чисел (аргумент для random_generate и random_cleanup).

См. также

CPC_CONFIG_


CPC_LOCK_FUNCS_

Структура настроек блокировок с ожиданием.

Если хотя бы одна из функций rwlock_init, rwlock_destroy, rwlock_wrlock или rwlock_unlock этой структуры не установлена (равна NULL), то провайдер функционирует в режиме без ожидающих блокировок.

При этом ответственность за недопущение параллельного вызова функций, влияющих на глобальное состояние провайдера (CPCAcquireContext, CPCReleaseContext, CPCSetProvParam (PP_USE_HARDWARE_RNG, PP_RANDOM)), приложение берёт на себя.

Кроме того, в этом режиме можно создавать контексты только с флагом CRYPT_NOSERIALIZE, исключающим ожидающие блокировки в данном контексте. (см. CPCAcquireContext).

Функция rwlock_rdlock - опциональна и, в случае её отсуствия, приравнивается к rwlock_wrlock. В случае отсуствия функйии rwlock_rdlock, все операции в рамках одного криптографического контекста будут выполнятся последовательно (однако, операции в разных контекстах будут выполнятся паралельно).

typedef struct CPC_LOCK_FUNCS_ {
  CPC_InitRWLock_Callback * rwlock_init;
  CPC_DestroyRWLock_Callback * rwlock_destroy;
  CPC_RDLockRWLock_Callback * rwlock_rdlock;
  CPC_WRLockRWLock_Callback * rwlock_wrlock;
  CPC_UnlockRWLock_Callback * rwlock_unlock;
  LPVOID lpArg;
} CPC_LOCK_FUNCS, *LPCPC_LOCK_FUNCS;

Члены

rwlock_init
Callback-функция для операции инициализации блокировки. Имеет тип CPC_InitRWLock.
rwlock_destroy
Callback-функция для операции уничтожения блокировки. Имеет тип CPC_DestroyRWLock.
rwlock_rdlock
Опциональная Callback-функция для операции разделяемой блокирования (блокировки на чтение). Имеет тип CPC_RDLockRWLock.
rwlock_wrlock
Callback-функция для операции эксклюзивной блокировки (блокировки на запись). Имеет тип CPC_WRLockRWLock.
rwlock_unlock
Callback-функция для операции разблокирования. Имеет тип CPC_UnlockRWLock.
lpArg
Аргумент для Callback-функций.

Примечания

Следует заметить, что одновременный доступ к криптографическим операциям над объеками ключей и хэш-функций приводит к неопределённым криптографческим результатам. Поэтому, при возникновении "соревнований" такого рода, ожидания не происходит. В этих случаях возвращаются ошибки NT_BAD_KEY и NTE_BAD_HASH.

См. также

CPC_CONFIG_


CPC_TIME_FUNCS_

Структура настроек работы со временем.

typedef struct CPC_TIME_FUNCS_ {
  CPC_GetTimeOfDay_Callback * get_time_of_day;
  CPC_RDTSC_Callback * read_tsc;
  LPVOID lpArg;
} CPC_TIME_FUNCS, *LPCPC_TIME_FUNCS;

Члены

get_time_of_day
Callback-функция для определения текущего времени. Имеет тип CPC_GetTimeOfDay.
read_tsc
Callback-функция для определения значения счетчика инструкций. Имеет тип CPC_RDTSC. Заполняется только на процессорах ARM, sparc-v8 (32).
lpArg
Аргумент для Callback-функции.

См. также

CPC_CONFIG_


CPC_ALG_PARAMS_

Структура настроек параметров алгоритмов.

typedef struct CPC_ALG_PARAMS_ {
  CHAR szOID_Hash[64];
  CHAR szOID_Cipher[64];
  CHAR szOID_Sign512_2012[64];
  CHAR szOID_DH512_2012[64];
  CHAR szOID_Sign_2001[64];
  CHAR szOID_DH_2001[64];
  BOOL fNoTables;
} CPC_ALG_PARAMS, *LPCPC_ALG_PARAMS;

Члены

szOID_Hash
OID параметров хеширования. Если эта строка пуста, используется szOID_GostR3411_94_CryptoProParamSet.
szOID_Cipher
OID параметров шифрования. Если эта строка пуста, используется szOID_Gost28147_89_CryptoPro_A_ParamSet.
szOID_Sign512_2012
OID параметров подписи ГОСТ Р 34.10-2012, 512 бит. Если эта строка пуста, используется szOID_tc26_gost_3410_12_512_paramSetA.
szOID_DH512_2012
OID параметров обмена на ключах ГОСТ Р 34.10-2012, 512 бит. Если эта строка пуста, используется szOID_tc26_gost_3410_12_512_paramSetA.
szOID_Sign_2001
OID параметров подписи ГОСТ Р 34.10-2001. Если эта строка пуста, используется szOID_GostR3410_2001_CryptoPro_A_ParamSet.
szOID_DH_2001
OID параметров обмена на ключах ГОСТ Р 34.10-2001. Если эта строка пуста, используется szOID_GostR3410_2001_CryptoPro_XchA_ParamSet.
fNoTables
Признак запрета создания больших таблиц возведения, предназначеных для ускорения операций. Рекомендуется при жестких ограничениях по доступной памяти (менее 2х мегабайт).

См. также

CP_PARAM_OIDS ,CPC_CONFIG_


CPC_INTERLOCKED_FUNCS_

Структура настроек примитивов синхронизации. Используется только на процессорах ARM и sparc-v8 (32).

typedef struct CPC_INTERLOCKED_FUNCS_ {
  CPC_InterlockedExchangeAdd_Callback * interlocked_exchange_add;
  CPC_InterlockedCASL_Callback * interlocked_casl;
  CPC_InterlockedCASLL_Callback * interlocked_casll;
} CPC_INTERLOCKED_FUNCS, *LPCPC_INTERLOCKED_FUNCS;

Члены

interlocked_exchange_add
Callback-функция для атомарной операции сложения. Имеет тип CPC_InterlockedExchangeAdd.
interlocked_casl
Callback-функция для атомарной операции условной замены четырёх байт. Имеет тип CPC_InterlockedCASL.
interlocked_casll
Callback-функция для атомарной операции условной замены восьми байт. Имеет тип CPC_InterlockedCASLL.

См. также

CPC_CONFIG_


CPC_CONFIG_

Структура инициализации и настройки провайдера уровня ядра ОС.

typedef struct CPC_CONFIG_ {
  DWORD cbSize;
  LPCPC_MEMORY_ARENA pArena;
  CPC_FAST_CODE FuncStruct;
  CPC_LOG_CONFIG logConfig;
  CPC_HARDWARE_RNG hardwareRNG;
  CPC_INTERLOCKED_FUNCS interlockedFuncs;
  CPC_LOCK_FUNCS lockFuncs;
  CPC_TIME_FUNCS timeFuncs;
  CPC_ALG_PARAMS algParams;
  DWORD MaxHandles;
  DWORD dwTesterPeriod;
  DWORD dwTesterTimeout;
  BOOL fNonSMP;
  const TCHAR * license;
} CPC_CONFIG, *LPCPC_CONFIG;

Члены

cbSize
Размер структуры. Должна быть равна sizeof (CPC_CONFIG).
pArena
Менеджер памяти (указатель на структуру CPC_MEMORY_ARENA_). Может быть создан с помощью функции CPCInitMemoryLF, или самостоятельно. Заполняется всегда.
FuncStruct
Функции захвата и освобождения расширений MMX/SSE2/SSSE3/AVX (структура CPC_FAST_CODE), а так же конфигурация их использования. Заполняется только на процессорах с архитектурой ia32/amd64.
logConfig
Настройки журнала (структура CPC_LOG_CONFIG_). Заполняется всегда.
hardwareRNG
Настройки аппаратного ДСЧ (структура CPC_HARDWARE_RNG_). Обязателен к заполнению в приложениях, удовлетворяющих требованиям KC2 или использующих CPCSetProvParam с аргументом PP_USE_HARDWARE_RNG.
interlockedFuncs
Настройки примитивов синхронизации (Структура CPC_INTERLOCKED_FUNCS_). Заполняется только на процессорах ARM и sparc-v8 (32).
lockFuncs
Настройки ждущих блокировок (Структура CPC_LOCK_FUNCS_). Рекомендуется к заполнению в приложениях, не обеспечивающих самостоятельно сериализацию доступа к провайдеру.
timeFuncs
Настройки работы со временем (Структура CPC_TIME_FUNCS_). Обязательна к заполнению.
algParams
Настройки параметров алгоритмов (Указатель на структуру CPC_ALG_PARAMS_). Опционально. Если заполнено нулями, используются параметры по умолчанию.
MaxHandles
Размер таблицы дескрипторов объектов (HANDLE). Максимальное количество дескрипторов в два раза меньше размера таблицы. Опционально, если равно нулю, устанавливается в 1048576 (32768 для мобильных платформ iOS, Андроид, CE).
dwTesterPeriod
Интервал самотестирования (в секундах). Опционально. Если равен нулю, используется DEF_TESTER_PERIOD (600). Установить период тестирования более MAX_TESTER_PERIOD = 15 минут нельзя. В Win32 user mode считывается значение TesterPeriod из ключа "Software\\Crypto Pro\\Cryptography\\CurrentVersion\\Parameters" раздела реестра HKEY_LOCAL_MACHINE.
dwTesterTimeout
Максимальный интервал самотестирования (в секундах). Опционально. Если равен нулю, используется MAX_TESTER_PERIOD (900) В Win32 user mode считывается значение TesterTimeout из ключа "Software\\Crypto Pro\\Cryptography\\CurrentVersion\\Parameters" раздела реестра HKEY_LOCAL_MACHINE.
fNonSMP
license
Строка, содержащая лицензию на продукт (94 символа, заканчивающиеся нулём). Заполняется всегда.

См. также

CPCCreateProvider


CPC_LFMM_CONFIG_

Интерфейс безблокировочного (lock-free) менеджера памяти.

Содержит прототипы функций безблокировочного менеджера памяти уровня CPC.

typedef struct CPC_LFMM_CONFIG_ {
  CPC_INTERLOCKED_FUNCS interlockedFuncs;
  LPVOID Buffer;
  LONG Size;
  BOOL fSMP;
  BOOL fStat;
  LONG * PoolSizes;
  DWORD nPools;
  DWORD nCPUs;
} CPC_LFMM_CONFIG, *LPCPC_LFMM_CONFIG;

Члены

interlockedFuncs
Настройки примитивов синхронизации (Структура CPC_INTERLOCKED_FUNCS).
Buffer
Указатель на блок памяти, из которого будет осуществляться распределение.
Size
Размер в байтах блока памяти, из которого будет осуществляться распределение. Должен быть больше или равен суммы размеров пулов (PoolSizes) + 65536.
fSMP
Признак того, что система может иметь более одного процессора и требуется синхронизация шины. Рекомендуется значение TRUE. Значение FALSE повышает производительность, но приводит к нестабильной работе на многопроцессорных системах.
fStat
Признак необходимости сбора статистики использования.
PoolSizes
Таблица размеров пулов памяти. Для CSP версии 3.6R3, например, при стандартном использовании в реализации IPsec рекомендуется следующее заполнение:

LONG PoolSizes[16];
...
memset(PoolSizes, 0, sizeof (PoolSizes));
PoolSizes[MP_PRIME_M] += 2*1024 * (MAX_SPI) + 1024*1024;
PoolSizes[MP_SEC_M] += 2*1024 * (MAX_SPI) + 1024*1024;
PoolSizes[MP_BIG] += 2*1024 * (MAX_SPI) + 1024*1024;
PoolSizes[MP_WORK] += 64*1024 * (MAX_SPI) + 5*1024*1024;
PoolSizes[MP_WORK_M] += 128*1024; .
nPools
Количество пулов памяти. Для CSP версии 3.6 и выше рекомендуется значение 16.
nCPUs
Количество процессоров в системе. Оптимизационный параметр. Рекомендуется значение 2 для двухпроцессорных систем.


CPC_MEMORY_STATS_

Структура статистики менеджера памяти.

typedef struct CPC_MEMORY_STATS_ {
  LONG nBytes;
  LONG nChunks;
  LONG Used;
  LONG Size;
} CPC_MEMORY_STATS, *LPCPC_MEMORY_STATS;

Члены

nBytes
Количество байт.
nChunks
Количество блоков.
Used
Объем использованной памяти.
Size
Размер кучи.

См. также

CPC_StatMemory ,CPC_MEMORY_ARENA_


CPC_MEMORY_ARENA_

Структура менеджера памяти. Указатель на неё входит в структуру CPC_CONFIG_. Все операции с динамической памятью провайдер осуществляет с помощью данной структуры.

typedef struct CPC_MEMORY_ARENA_ {
  CPC_ValidateMemory_Callback * pValidateMemory;
  CPC_DoneMemory_Callback * pDoneMemory;
  CPC_AllocMemory_Callback * pAllocMemory;
  CPC_FreeMemory_Callback * pFreeMemory;
  CPC_StatMemory_Callback * pStatMemory;
  CPC_MemoryException_Callback * pHandleException;
  LPVOID lpArg;
} CPC_MEMORY_ARENA, *LPCPC_MEMORY_ARENA;

Члены

pValidateMemory
Функция проверки корректности состояния кучи. Имеет тип CPC_ValidateMemory.
pDoneMemory
Деструктор кучи. Имеет тип CPC_DoneMemory.
pAllocMemory
Функция выделения памяти. Имеет тип CPC_AllocMemory.
pFreeMemory
Функция освобождения памяти. Имеет тип CPC_FreeMemory.
pStatMemory
Функция сбора статистики использования памяти. Имеет тип CPC_StatMemory.
pHandleException
Функция обработки исключений при выделении памяти. Имеет тип CPC_MemoryException.
lpArg
Аргумент функции обработки исключений.

См. также

CPC_CONFIG_ ,CPCCreateProvider


Функции генерации и работы с ключами

Функции генерации и работы с ключами предназначены для генерации ключей и ключевых пар (закрытый/открытый ключи), а также для обработки различных типов ключей, используемых в криптопровайдере.

Функции | Описание
CPCGenKey | Функция CPCGenKey() генерирует случайные криптографические ключи или ключевую пару (закрытый/открытый ключи).
CPCDestroyKey | Функция CPCDestroyKey() удаляет ключ, передаваемый через параметр hKey. После удаления ключ (дескриптор ключа) не может использоваться.
CPCDeriveKey | Функция CPCDeriveKey() производит криптографические ключи сессии на основе значения хэш-функции, вычисленной по другим ключам, паролям или любым другим данным пользователя.
CPCDuplicateKey | Функция CPCDuplicateKey() создает точную копию заданного ключа, включая все его переменные, определяющие внутреннее состояние ключа (вектор IV, режим шифрования, режим преобразования, режим дополнения, набор узлов замены и прочее).
CPCExportKey | Функция CPCExportKey() используется для экспорта криптографических ключей из ключевого контейнера криптопровайдера, сохраняя их в защищённом виде.
CPCGenRandom | Функция CPCGenRandom() заполняет буфер случайными байтами.
CPCGetKeyParam | Функция CPCGetKeyParam() возвращает параметры ключа.
CPCGetUserKey | Функция CPCGetUserKey() возвращает дескриптор одной из долговременных ключевых пар в ключевом контейнере.
CPCImportKey | Функция CPCImportKey() используется для импорта криптографического ключа из ключевого блоба в контейнер криптопровайдера, для диверсификации ключа с использованием данных, передаваемых через ключевой блоб в соответствии с RFC 4357, п. 7., а так же для диверсификации ключа в соответствии с алгоритмами, описанным в п. 4.4, 4.5 рекомендаций по стандартизации "Криптографические алгоритмы, сопутствующие применению алгоритмов электронной цифровой подписи и функции хэширования".
CPCSetKeyParam | Функция CPCSetKeyParam() устанавливает параметры ключа.


CPCGenKey

Функция CPCGenKey() генерирует случайные криптографические ключи или ключевую пару (закрытый/открытый ключи).

DWORD CPCAPI CPCGenKey(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  ALG_ID AlgId,
  DWORD dwFlags,
  HCRYPTKEY * phKey
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
AlgId
[in] Идентификатор алгоритма шифрования или ЭП, для которого производится ключ. Могут быть произведены ключи следующих классов:
  • временные симметричные ключи (сессионные ключи);
  • временные (эфемерные) ключевые пары алгоритмов Диффи-Хеллмана;
  • долговременные ключевые пары, сохраняемые в ключевом контейнере.

Возможные сессионные ключи:
Значение AlgId | Описание
CALG_G28147 | Ключ шифрования и/или имитозащиты данных по ГОСТ 28147-89. Впоследствии этот ключ можно пометить как ключ для импорта/экспорта с помощью функции CPCSetKeyParam().
CALG_TLS1_MASTER | Специальный ключ для реализации протокола TLS.
Возможные эфемерные ключи Диффи-Хеллмана:
AlgId | Описание
CALG_UECSYMMETRIC_EPHEM | Эфемерный симметричный ключ. Предназначен для управления ключами в системе Универсальная электронная карта.
CALG_DH_EL_EPHEM | Эфемерная ключевая пара на базе ГОСТ Р 34.10-2001. Предназначена для обмена сессионными ключами.
CALG_DH_GR3410_12_256_EPHEM | Эфемерная ключевая пара на базе ГОСТ Р 34.10-2012 с длиной ключа 256 бит. Предназначена для обмена сессионными ключами.
CALG_DH_GR3410_12_512_EPHEM | Эфемерная ключевая пара на базе ГОСТ Р 34.10-2012 с длиной ключа 512 бит. Предназначена для обмена сессионными ключами.
Возможные долговременные ключевые пары:
AlgId | Описание
AT_KEYEXCHANGE | Производится ключевая пара, сохраняемая в ключевом контейнере. Предназначена для обмена сессионными ключами и ЭП. В качестве алгоритма ключевой пары выбирается алгоритм по умолчанию для hProv, параметр PP_DHOID функции CPGetProvParam().
CALG_DH_EL_SF | Производится ключевая пара согласно ГОСТ Р 34.10-2001. Предназначена для обмена сессионными ключами и ЭП, в ключевой контейнер не заносится.
CALG_DH_GR3410_12_256_SF | Производится ключевая пара согласно ГОСТ Р 34.10-2012 с длиной ключа 256 бит. Предназначена для обмена сессионными ключами и ЭП, в ключевой контейнер не заносится.
CALG_DH_GR3410_12_512_SF | Производится ключевая пара согласно ГОСТ Р 34.10-2012 с длиной ключа 512 бит. Предназначена для обмена сессионными ключами и ЭП, в ключевой контейнер не заносится.
AT_SIGNATURE | Производится ключевая пара, сохраняемая в ключевом контейнере. Предназначена для ЭП. В качестве алгоритма ключевой пары выбирается алгоритм по умолчанию для hProv, параметр PP_SIGNATUREOID функции CPGetProvParam().
CALG_GR3410EL | Производится ключевая пара согласно ГОСТ Р 34.10-2001, в ключевой контейнер не заносится.
CALG_GR3410_12_256 | Производится ключевая пара согласно ГОСТ Р 34.10-2012 с длиной ключа подписи 256 бит, в ключевой контейнер не заносится.
CALG_GR3410_12_512 | Производится ключевая пара согласно ГОСТ Р 34.10-2012 с длиной ключа подписи 512 бит, в ключевой контейнер не заносится.
AT_UECSYMMETRICKEY | Производится симметричный пользовательский ключ. Предназначен для использования как мастерключ в системе производства ключей карт. Заносится в ключевой контейнер.
CALG_UECSYMMETRIC | Производится симметричный ключ. Если генерация ключа производится в именованном контексте, где нет ключа AT_UECSYMMETRICKEY, создаваемый ключ заносится в ключевой контейнер. Предназначен для использования как мастер-ключ в системе производства ключей карт. В ключевой контейнер заносится, если соответствующий AT_UECSYMMETRICKEY в ключевом контейнере отсутствует.
dwFlags
[in] Флаги определяют признаки производимого ключа. Размеры ключей подписи и ключей обмена могут быть установлены при выработке ключа. Размер ключа устанавливается в старших 16 битах параметра dwFlags, эти 16 бит представляют длину открытого ключа в битах. Длина открытого ключа равна 512 для ГОСТ Р 34.10-2001 и ГОСТ Р 34.10-2012, длина ключа подписи 256 бит, и 1024 для ГОСТ Р 34.11-2012, длина ключа подписи 512 бит. Если длина ключа указана явно, она должна строго соответствовать алгоритму ключа и типу используемого провайдера. В настоящее время определены следующие флаги:
Значение dwFlags | Описание
CRYPT_EXPORTABLE Если этот флаг установлен, то произведённый ключ может быть передан из криптопровайдера в ключевой блоб через функцию CPCExportKey(). Если этот флаг не установлен, ключ не будет экспортируемым и будет доступен только в пределах текущей сессии приложению, которое создало этот ключ. Действие этого флага не распространяются на открытые ключи ключевых пар.

Экспорт закрытых ключей ключевых пар 2001 года возможен только на эфемерных ключах и ключах с алгоритмом CALG_PRO_EXPORT и CALG_PRO12_EXPORT. Экспорт закрытых ключей ключевых пар 2012 года возможен только на эфемерных ключах и ключах с алгоритмом CALG_PRO12_EXPORT.
CRYPT_ARCHIVABLE Если этот флаг установлен, то произведённый ключ может быть передан из криптопровайдера в ключевой блоб через функцию CPCExportKey() только в в том контексте провайдера (сессии), в котором он был создан, и только до вызова функции CPCDestroyKey() на дескриптор ключа. Данный флаг не может быть установлен одновременно с флагом CRYPT_EXPORTABLE.

При экспорте ключа с этим флагом, создаётся CRYPT_PRIVATEKEYBLOB со сброшенным флагом pkaExportable.

Экспорт закрытых ключей ключевых пар 2001 года возможен только на эфемерных ключах и ключах с алгоритмом CALG_PRO_EXPORT и CALG_PRO12_EXPORT. Экспорт закрытых ключей ключевых пар 2012 года возможен только на эфемерных ключах и ключах с алгоритмом CALG_PRO12_EXPORT.
CRYPT_USER_PROTECTED | Если этот флаг установлен, то при любом запросе на доступ к носителю закрытого ключа пользователя выводится окно диалога, запрашивающего право доступа к ключу.
CRYPT_PREGEN | Если этот флаг установлен, то генерируется "пустая" ключевая пара обмена. Параметры этой ключевой пары должны быть установлены с использованием функции CPCSetKeyParam().
CP_CRYPT_DH_ALLOWED | Если этот флаг установлен, то закрытый ключ произведенной ключевой пары может быть использован для согласования сессионного ключа с помощью алгоритма Диффи-Хеллмана (VKO). Если данный флаг не указан, то для ключевых пар электронной подписи 2012 года согласование будет запрещено. Для ключевых пар обмена разрешено всегда.
phKey
[out] Адрес, по которому функция копирует дескриптор сформированного ключа (ключевой пары открытый/закрытый ключи).

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_ALGID | Параметр AlgId определяет алгоритм, не поддерживаемый криптопровайдером. Эта ошибка возвращается также в случае попытки генерации пользовательских ключей AT_KEYEXCHANGE и AT_SIGNATURE криптопровайдером, сертифицированным по уровню KC2 и выше, при отсутствии физического ДСЧ в составе СКЗИ.
NTE_BAD_FLAGS | Величина dwFlags имеет ошибочное значение.
NTE_NO_MEMORY | Криптопровайдер во время операции исчерпал память.
NTE_FAIL | Ошибка при считывании данных из системного реестра. см. Дополнительные параметры и определения .
SCARD_W_CANCELLED_BY_USER | Пользователь прервал операцию нажатием клавиши Cancel
SCARD_W_WRONG_CHV | Пользователь ввёл неправильный пароль или пароль, установленный функцией SetProvParam(), неправильный
SCARD_E_INVALID_CHV | Пользователь ввёл пароль с нарушением формата или пароль, установленный функцией SetProvParam(), имеет неправильный формат. Например, пароль имеет недопустимую длину или содержит недопустимые символы.
SCARD_W_CHV_BLOCKED | Ввод Pin-кода был заблокирован смарт-картой, т.к. исчерпалось количество попыток разрешенное картой для ввода.
NTE_TOKEN_KEYSET_STORAGE_FULL | Недостаточно места на носителе для сохранения информации.
NTE_SILENT_CONTEXT | Операция не может быть выполнена без пользовательского интерфейса.
SCARD_W_REMOVED_CARD | Носитель контейнера был удален из считывателя.
NTE_EXISTS | Попытка создания ключа в контейнере, где ключ уже существует.

Примечания

Если при запросе функции CPCAcquireContext() был создан ключевой контейнер с признаком CRYPT_VERIFYCONTEXT, прикладные программы не могут создавать долговременные ключевые пары. В этом случае функция CPCGenKey() возвращает код ошибки NTE_PERM. Когда ключи порождаются для симметричного шифрования, по умолчанию ключ будет установлен в шифратор в режиме гаммирования с обратной связью (CFB) со случайным начальным вектором. Эти параметры могут быть получены с использованием функции CPCSetKeyParam() и частично изменены функцией CPCSetKeyParam()

Функция CPCGenKey() получает ключ с программного ДСЧ криптопровайдера. Для инициализации программного ДСЧ с физического ДСЧ, следует использовать функцию CPCSetProvParam() с флагом PP_USE_HARDWARE_RNG. В варианте исполнения КС2 без такой инициализации генерация ключей невозможна.

Ключи AT_UECSYMMETRICKEY, CALG_UECSYMMETRIC, CALG_UECSYMMETRIC_EPHEM имеют ограниченный функционал, предназначены для использования в ключевых системах Универсальных Электронных Карт. Данные ключи не рекомендуется использоваться в иных системах.

Заметим, что, в соответствии с общепринятой мировой практикой, в качестве длины ключа при создании указывается именно длина открытого ключа, а не присутствующая в идентификаторах алгоритмов и oid'ах длина модуля, по которому производятся операции. В отличие от, например, алгоритма RSA (в реализациях которого открытая экспонента, как правило, фиксирована, а открытый ключ представляет собой модуль n), длина открытого ключа в стандартах подписи, основанных на операциях в группе точек эллиптической кривой (ECDSA, ГОСТ Р 34.10-2001, ГОСТ Р 34.10-2012), в два раза превосходит длину модуля.

При генерации ключа подписи/обмена выбор соответствующего алгоритма производится в зависимости от типа используемого провайдера. Провайдер типа PROV_GOST_2001_DH создает ключи в соответствии с алгоритмом ГОСТ Р 34.10-2001, используется функция хэширования в соответствии с ГОСТ Р 34.11-94. Провайдер типа PROV_GOST_2012_256 создает ключи длины 256 бит в соответствии с алгоритмом ГОСТ Р 34.10-2012, в качестве алгоритма хэширования использует алгоритм ГОСТ Р 34.11-2012 (256 бит). Провайдер типа PROV_GOST_2012_512 создает ключи длины 512 бит в соответствии с алгоритмом ГОСТ Р 34.10-2012, в качестве алгоритма хэширования использует алгоритм ГОСТ Р 34.11-2012 (512 бит).

При генерации сессионного ключа CALG_G28147 параметр KP_CIPHEROID полученного ключа по умолчанию принимает установленное для провайдера значение PP_CIPHEROID, либо, после загрузки ключей из контейнера с помощью CPCGetUserKey(), oid параметров шифрования, установленный в этом контейнере.

Для создания эфемеральных ключей необходимого типа с определёнными параметрами алгоритма Диффи-Хеллмана необходимо: сгенерировать "пустую" ключевую пару командой CPCGenKey(hCSP, hProv, algId, CRYPT_PREGEN, &hKey); затем установить тип параметров алгоритмов Диффи-Хеллмана командой CPCSetKeyParam(hCSP, hProv, hKey, KP_DHOID, pbOIDdata, 0); после чего непосредственно выработать значение ключа с помощью команды CPCSetKeyParam(hCSP, hProv, hKey, KP_X, NULL, 0);

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.
Ядро ОС: При использовании в ядре ОС CPCGenKey допустимо вызывать только для производства ключей сессии и эфемеральных ключей.

См. также

CPCDestroyKey() ,CPCExportKey() ,CPCImportKey() ,CPCGetKeyParam() ,CPCSetKeyParam() ,CPCReleaseContext() ,CPGenKey в MS CSP World Wide Web link ,CryptGenKey в MS CryptoAPI 2.0 World Wide Web link


CPCDestroyKey

Функция CPCDestroyKey() удаляет ключ, передаваемый через параметр hKey. После удаления ключ (дескриптор ключа) не может использоваться.

DWORD CPCAPI CPCDestroyKey(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  HCRYPTKEY hKey
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
hKey
[in] Дескриптор удаляемого ключа.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
NTE_BAD_KEY | Дескриптор удаляемого ключа hKey ошибочен.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CPCDeriveKey() ,CPCGenKey() ,CPCGetUserKey() ,CPDestroyKey в MS CSP World Wide Web link ,CryptDestroyKey в MS CryptoAPI 2.0 World Wide Web link


CPCDeriveKey

Функция CPCDeriveKey() производит криптографические ключи сессии на основе значения хэш-функции, вычисленной по другим ключам, паролям или любым другим данным пользователя.

DWORD CPCAPI CPCDeriveKey(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  ALG_ID AlgId,
  HCRYPTHASH hBaseData,
  DWORD dwFlags,
  HCRYPTKEY * phKey
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
AlgId
[in] Идентификатор алгоритма шифрования, для которого производится ключ.
Значение AlgId | Описание
CALG_G28147 | Ключ шифрования и/или имитозащиты данных по ГОСТ 28147-89. Впоследствии этот ключ может быть преобразован с помощью функции CPCSetKeyParam() в ключ, на котором возможен экспорт/импорт других ключей.
CALG_TLS1_ENC_KEY | Ключ шифрования на основе объекта TLS1_MASTER_HASH.
CALG_TLS1_MAC_KEY | Ключ имитозащиты на основе объекта TLS1_MASTER_HASH.
CALG_UECSYMMETRIC CALG_UECSYMMETRIC_EPHEM CALG_G28147 | Ключи различных типов на основе объекта CALG_UECMASTER_DIVERS. Если именованный ключевой контекст не содержит ключа AT_UECSYMMETRICKEY, ключ CALG_UECSYMMETRIC заносится в ключевой контейнер.
hBaseData
[in] Дескриптор объекта функции хэширования, используемый для обработки входных данных. Во время вызова функции объект хэша "закрывается".
Для ГОСТ Р 34.11-94 и ГОСТ Р 34.11-2012 (и HMAC-ов на их основе) проводится дополнение до размера блока (если требуется), исполняются шаговые функции для последнего блока (если требуется), для длины и для контрольной суммы.
Для ГОСТ 28147-89 в режиме имитовставки проводится дополнение до размера блока (если требуется), и исполняется шаговая функции для последнего блока (если требуется).
Расчёт хэш-функции может быть продолжен с помощью:
  • последующего вызова *SetHashParam(HP_OPEN, TRUE) для CSP 3.6 и выше;
  • предварительного вызова *DuplicateHash() - стандартный для Microsoft способ;
    Для хэш с алгоритмами CALG_MD5, CALG_SHA1, CALG_SHA_256, CALG_SHA_384, CALG_SHA_512, CALG_G28147_IMIT функция может отработать успешно, но значение ключа всегда будет неопределённым.
    Для хэш с алгоритмом CALG_SHAREDKEY_HASH функция вырабатывает очередную компоненту ключа.
    Для хэш с алгоритмом CALG_FITTINGKEY_HASH функция вырабатывает собранный из компонентов ключ при условии, что все компоненты собраны функцией *HashSessionKey().
dwFlags
[in] Флаги определяют признаки производимого ключа сессии. В настоящее время определены следующие значения флагов:
Значение dwFlags | Описание
CRYPT_EXPORTABLE | Если флаг установлен, то произведённый ключ может быть передан из криптопровайдера в ключевой блоб через функцию CPCExportKey(). Если флаг не установлен, ключ не будет экспортируемым и будет доступен только в пределах текущей сессии приложению, которое создало этот ключ. Действие этого флага не распространяются на открытый ключ ключевых пары.
CRYPT_SERVER | Если при работе с TLS флаг установлен, то создается ключ шифрования сервера, если не установлен - создается ключ шифрования клиента.
CP_CRYPT_GETUPPERKEY | Если флаг установлен, то для ГОСТ Р 34.11-2012 512 бит (и HMAC-ов на его основе) функция будет использовать старшие 32 байта хэш-значения. Не может быть использован с другими алгоритмами.
phKey
[out] Адрес, по которому функция копирует дескриптор произведённого ключа.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_ALGID | Параметр AlgId определяет алгоритм, который не поддерживается криптопровайдером.
NTE_BAD_FLAGS | Величина dwFlags имеет ошибочное значение.
NTE_BAD_HASH | Дескриптор хэша ошибочен.
NTE_NO_MEMORY | Криптопровайдер во время операции исчерпал память.
NTE_FAIL | Ошибка при считывании данных из системного реестра. см. Дополнительные параметры и определения .

Примечания

Если на вход подаётся фиксированный набор данных, то функция создаёт один и тот же ключ. В этом случае создаваемый ключ можно использовать только для шифрования данных или экспорта ключей на ключевые носители. Использовать его для шифрования данных или экспорта ключей, помещаемых на диск или передаваемых по каналу связи, не рекомендуется.

Использование алгоритмов CALG_MD5, CALG_SHA_256, CALG_SHA_384, CALG_SHA_512 не входит в функционал СКЗИ КриптоПро CSP 4.0, относящийся к действию сертификата ФСБ.

Режимы шифрования, преобразования ключа, дополнения открытого текста до кратности блока, набор узлов замены для получаемого ключа устанавливаются такие же, как и для вновь созданного ключа (см. CPCSetKeyParam()).

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CPCDestroyKey() ,CPCGenKey() ,CPDeriveKey в MS CSP World Wide Web link ,CryptDeriveKey в MS CryptoAPI 2.0 World Wide Web link


CPCDuplicateKey

Функция CPCDuplicateKey() создает точную копию заданного ключа, включая все его переменные, определяющие внутреннее состояние ключа (вектор IV, режим шифрования, режим преобразования, режим дополнения, набор узлов замены и прочее).

DWORD CPCAPI CPCDuplicateKey(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  HCRYPTKEY hKey,
  DWORD * pdwReserved,
  DWORD dwFlags,
  HCRYPTKEY * phKey
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
hKey
[in] Дескриптор исходного (копируемого) ключа. Возможно дублирование только ключей класса ALG_CLASS_DATA_ENCRYPT (см. CryptGetProvParam в MS CryptoAPI 2.0 World Wide Web link ).
pdwReserved
[in] Параметр зарезервирован для будущего использования и должен быть NULL.
dwFlags
[in] Параметр зарезервирован для будущего использования и должен быть нулевым.
phKey
[out] Адрес, по которому функция возвращает дескриптор скопированного ключа.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_KEY | Дескриптор исходного ключа ошибочен.
NTE_BAD_FLAGS | Параметр dwFlags имеет ненулевое значение.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CPCDestroyKey() ,CPDuplicateKey в MS CSP World Wide Web link ,CryptDuplicateKey в MS CryptoAPI 2.0 World Wide Web link


CPCExportKey

Функция CPCExportKey() используется для экспорта криптографических ключей из ключевого контейнера криптопровайдера, сохраняя их в защищённом виде.

DWORD CPCAPI CPCExportKey(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  HCRYPTKEY hKey,
  HCRYPTKEY hExpKey,
  DWORD dwBlobType,
  DWORD dwFlags,
  BYTE * pbData,
  DWORD * pdwDataLen
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
hKey
[in] Дескриптор экспортируемого ключа.
hExpKey
[in] Дескриптор ключа, на котором осуществляется криптографическая защита экспортируемого ключа. Необходимо, чтобы этот ключ был общим с получателем корреспонденции. Зашифрованные данные ключа помещаются в ключевой блоб, предназначенный для внешнего хранения и передачи по каналам связи. Алгоритмы функции экспорта ключей гарантируют, что только пользователь предназначения сможет использовать этот ключевой блоб. Для защиты ключа используется алгоритм, указанный при создании ключа экспорта. Если ключевой блоб не будет зашифрован (например, если тип ключевого блоба - PUBLICKEYBLOB), этот параметр должен быть нулевым.
dwBlobType
[in] Тип ключевого блоба, предназначенного для экспорта ключа. В настоящее время определены три типа ключевых блобов:
Тип | Использование
SIMPLEBLOB | Используется для транспортировки симметричных ключей CALG_G28147, CALG_UECSYMMETRIC. pbData указывает на структуру CRYPT_SIMPLEBLOB .
OPAQUEKEYBLOB | Используется для транспортировки ключа сессии с накопленным состоянием. pbData указывает на структуру CRYPT_OPAQUEBLOB .
PUBLICKEYBLOB | Используется для транспортировки открытых ключей. pbData указывает на структуру CRYPT_PUBLICKEYBLOB .
PRIVATEKEYBLOB | Используется для транспортировки закрытых ключей). pbData указывает на структуру CRYPT_PRIVATEKEYBLOB .
dwFlags
[in] Значения флагов. Должен быть нулевым во всех случаях за исключением экспорта ключевой пары в PUBLICKEYBLOB. В настоящее время определены следующие значения флагов:
Значение dwFlags | Описание
CRYPT_PUBLICCOMPRESS | Если флаг установлен, то отрытый ключ в PUBLICKEYBLOB представляется парой (x,b), где байт b равен 2, если координата y чётная и 3 в противном случае. Если флаг не установлен, то отрытый ключ в PUBLICKEYBLOB представляется координатами (x,y) точки эллиптической кривой.
CP_CRYPT_CALCULATE_PUBLIC_KEY | Если флаг установлен, то открытый ключ будет перевычислен даже при наличии сертификата.
pbData
[in] Указатель на буфер данных, в который функция копирует ключевой блоб. Если значение этого параметра NULL, функция устанавливает по адресу pdwDataLen значение необходимой длины буфера и возвращает TRUE.
pdwDataLen
[in/out] Указатель на буфер, содержащий длину ключевого блоба. При вызове функции указанный параметр содержит число байтов в буфере pbData. После выполнения функции параметр будет установлен числом байтов данных, скопированных в буфер pbData. Если буфер, соответствующий pbData, недостаточно большой, будет возвращён код ошибки ERROR_MORE_DATA через функцию SetLastError(). В этом случае требуемый размер буфера возвращается в pdwDataLen. Если эта функция завершается с кодом ошибки, отличным от ERROR_MORE_DATA, в этом параметре возвращается ноль.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
ERROR_MORE_DATA | Буфер pbData недостаточно большой, чтобы копировать затребованные данные.
NTE_BAD_FLAGS | Величина dwFlags имеет ненулевое значение.
NTE_BAD_KEY | Один или оба из ключей, указанных hKey и hExpKey, не действительны.
NTE_BAD_KEY_STATE | Попытка экспорта ключа, когда право экспорта криптопровайдером не предоставлено; попытка экспорта на ключе, для которого разрешение экспортировать не установлено.
NTE_BAD_TYPE | dwBlobType параметр определяет неизвестный тип блоба.
NTE_NO_MEMORY | Криптопровайдер во время операции исчерпал память.
NTE_FAIL | Ошибка при считывании данных из системного реестра. см. Дополнительные параметры и определения .
SCARD_W_CANCELLED_BY_USER | Пользователь прервал операцию.

Примечания

PUBLICKEYBLOB длины 69 байт в настоящее время не может использоваться в составе сертификата открытого ключа. Блобы данного вида критичны к искажениям, поэтому должны использоваться в приложениях с контролем целостности.

Для экспорта сессионных ключей могут использоваться алгоритмы CALG_SIMPLE_EXPORT, CALG_PRO_EXPORT и CALG_PRO12_EXPORT. Долговременные ключи 2001 года могут быть экспортированы при помощи алгоритмов CALG_PRO_EXPORT и CALG_PRO12_EXPORT. К ключам 2012 года применим только алгоритм экспорта CALG_PRO12_EXPORT.

Для ключей 2012 года, которые используют параметры алгоритма ГОСТ 28147, отличные от параметров по умолчанию ("1.2.643.7.1.2.5.1.1", вариант ТК26 Z), идентификатор соответствующих параметров указывается в ключевом блобе. При использовании параметров по умолчанию идентификатор в блоб не записывается.

Если симметричный ключ использует параметры шифрования "1.2.643.7.1.2.5.1.1" (вариант ТК26 Z), то при экспорте данного ключа длина ключевого блоба будет больше, чем при использовании других параметров. Для обеспечения корректности работы с памятью рекомендуется предварительно запрашивать значение необходимой длины буфера для возвращаемых данных.

В случае, если производится экспорт SIMPLEBLOB возможна организация многопоточной работы функции CPCExportKey(). Для этого необходимо заранее создать специальный объект HCRYPTMODULE с помощью функции CPCGetProvParam() с флагом PP_CREATE_THREAD_CSP; данный объект в дальнейшем следует передавать функции CPCExportKey() в качестве первого параметра. Также необходимо в dwFlags передать флаг CP_CRYPT_NOKEYWLOCK, при этом ключ hExpKey блокируется только на чтение. Корректность работы функции и целостность ключа импорта гарантируются криптопровайдером.

Рекомендуется, по возможности, при выработке открытых ключей двукратно производить выработку открытого ключа и осуществлять проверку равенства результатов.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.
Ядро ОС: Поддерживается только типы SIMPLEBLOB и OPAQUEKEYBLOB.

См. также

CRYPT_SIMPLEBLOB ,CRYPT_OPAQUEBLOB ,CPCImportKey() ,CPExportKey в MS CSP World Wide Web link ,CryptExportKey в MS CryptoAPI 2.0 World Wide Web link


CPCGenRandom

Функция CPCGenRandom() заполняет буфер случайными байтами.

DWORD CPCAPI CPCGenRandom(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  DWORD dwLen,
  BYTE * pbBuffer
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
dwLen
[in] Число байтов случайных данных, которые будут произведены.
pbBuffer
[in/out] Указатель на буфер, в который копируются случайные данные. Длина этого буфера в байтах передаётся параметром dwLen.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_FAIL RPE_FAIL_STATBUFFER | Неудовлетворительная статистика датчика случайных чисел, контролируемая при открытии контейнера. Эта ошибка носит вероятностный характер. Для корректно работающей программы вероятность возникновения ошибки не превышает 10^(-16).
NTE_FAIL RPE_FAIL_TESTBUFFER | Неудовлетворительная постоянно действующая статистика датчика случайных чисел. Эта ошибка носит вероятностный характер. Для корректно работающей программы вероятность возникновения ошибки не превышает 10^(-16).
NTE_KEYSET_ENTRY_BAD | Данные неверно считаны из системного реестра.

Примечания

Функция CPCGenRandom() получает случайные числа с программного ДСЧ контекста криптопровайдера hProv, который инициализируется при выполнении функции CPCAcquireContext() c накопленного в контейнере ключевого носителя состояния ДСЧ и установленного в системе физического ДСЧ.

В случае, если контекст криптопровайдера открыт в режиме CRYPT_VERIFYCONTEXT и в системе не установлено физического ДСЧ, программный ДСЧ инициализируется с накапливаемого в реестре общесистемного состояния ДСЧ и накопленных состояний ДСЧ всех открытых ранее контейнеров ключевых носителей в рамках времени жизни разделяемой библиотеки "КриптоПро CSP 4.0". Для гарантированной инициализации ДСЧ с физического или БиоДСЧ, в случае если ранее могли не открываться контейнеры ключевых носителей, следует использовать функцию CPCSetProvParam() с флагом PP_USE_HARDWARE_RNG.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.
Ядро ОС: Перед получением случайных чисел требуется инициализировать ДСЧ контекста криптопровайдера hProv с помощью параметра PP_RANDOM функции CPCSetProvParam().

См. также

CPCSetProvParam() ,CPGenRandom в MS CSP World Wide Web link ,CryptGenRandom в MS CryptoAPI 2.0 World Wide Web link


CPCGetKeyParam

Функция CPCGetKeyParam() возвращает параметры ключа.

DWORD CPCAPI CPCGetKeyParam(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  HCRYPTKEY hKey,
  DWORD dwParam,
  BYTE * pbData,
  DWORD * pdwDataLen,
  DWORD dwFlags
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
hKey
[in] Дескриптор ключа, параметры которого возвращаются.
dwParam
[in] Параметр, принимающий следующие возможные значения:
Значение dwParam | Содержимое буфера pbData
KP_ALGID | Идентификатор алгоритма (ALG_ID), соответствующий данному ключу.
KP_PERMISSIONS | Флаги разрешения использования ключа. Возвращаются в виде переменной типа DWORD.
KP_IV | Возвращает начальное значение вектора инициализации (IV или синхропосылки) алгоритма шифрования. Если ключ использовался в вызове CPCEncrypt() или CPCDecrypt() с параметром Final = FALSE, то значение данного параметра остается неизменным до вызова соответствующей функции с параметром Final = TRUE. По завершению работы функции начальное значение синхропосылки изменяется на случайное. До вызова CPCEncrypt() или CPCDecrypt() с параметром Final = FALSE значение параметра может быть изменено с помощью функции CPCSetKeyParam().
KP_IV_BLOB | Возвращает начальное значение вектора инициализации (IV или синхропосылки) для алгоритма VKO GOST R 34.10-2012-256.
KP_CERTIFICATE | Получение сертификата из контейнера (из носителя).
KP_MODE Режим алгоритма шифрования. Возвращается в виде переменной типа DWORD. Используются режимы шифрования:
  • CRYPT_MODE_ECB - блочный шифр простой замены ГОСТ 28147-89;
  • CRYPT_MODE_CNT - шифрование гаммированием ГОСТ 28147-89;
  • CRYPT_MODE_CFB - шифрование гаммированием с обратной связью ГОСТ 28147-89;
  • CRYPT_MODE_CBCRFC4357 - блочный шифр с обратной связью на базе ГОСТ 28147-89, согласно RFC 4357;
  • CRYPT_MODE_CBCSTRICT - блочный шифр с обратной связью на базе ГОСТ 28147-89, шифртекст блока всегда является IV для следующего. Рекомендуется для использования только для обеспечения совместимости с существующими продуктами.
KP_MODE_BITS | Глубина обратной связи. Возвращается в виде переменной типа DWORD. Значение этой величины равно 64, что соответствует режиму гаммирования с обратной связью ГОСТ 28147-89.
KP_MIXMODE Режим преобразования ключа. Возвращается в виде переменной типа DWORD. Используются режимы преобразования:
  • CRYPT_PROMIX_MODE - преобразование после зашифрования каждых 1024 байт информации,
  • CRYPT_SIMPLEMIX_MODE - без преобразования.
KP_KEYLEN | Длина ключа в битах. Возвращается в виде переменной типа DWORD. Для ключей шифрования в параметре pbData возвращается длина ключа, для ключевых пар возвращается длина открытого ключа.
KP_BLOCKLEN | Длина блока шифрования, обрабатываемого криптопровайдером. Возвращается в виде переменной типа DWORD. В случае сессионного ключа если для ключа установлен режим блочного шифрованя (CRYPT_MODE_ЕСB, CRYPT_MODE_CBС), в параметре pbData устанавливается размер блока алгоритма ГОСТ 28147-89, если установлен режим поточного шифрования (CRYPT_MODE_CNT, CRYPT_MODE_CFB), в параметре pbData устанавливается значение оптимального с точки зрения скорости шифрования размера блока, принимаемого от приложения (в настоящее время 8Кбит). В случае ключевой пары в параметре pbData устанавливается число бит модуля q для ключей на базе эллиптической кривой (ГОСТ Р 34.10-2001 и ГОСТ Р 34.10-2012).
KP_CIPHEROID | Идентификатор узла замены, устанавливаемого приложением. Строковая величина с признаком конца строки.
KP_DHOID | Идентификатор алгоритма Диффи-Хеллмана. Строка, заканчивающаяся нулем.
KP_SIGNATUREOID | Идентификатор алгоритма подписи. Строка, заканчивающаяся нулем.
KP_HASHOID | Идентификатор функции хэширования, устанавливаемой приложением. Строка, заканчивающаяся нулем.
KP_DELTA | Возвращает значение дельты после установки на пользовательский ключ значение синхропосылки. В pbData указавает на данные – 32 байта дельты. Специфика протокола ООО "КРИПТО-ПРО" взаимодействия с функциональным ключевым носителем.
KP_FP | Возвращает первые 8 байт открытого ключа.
KP_NOTAFTER | См. Сроки действия долговременных ключей в "КриптоПро CSP 4.0" .
KP_UEC_DERIVE_COUNTER | Для ключа типа AT_UECSYMMETRICKEY возвращает значение счетчика ключей, полученных диверсификацией данного. Возвращается в виде переменной типа DWORD.
pbData
[out] Указатель на буфер данных параметра. Функция копирует соответствующие параметру данные в буфер. Формат этих данных зависит от значения dwParam. Если параметр - NULL, то данные не копируются. Требуемый размер буфера в байтах возвращается в pdwDataLen. Подробнее см. Возвращение данных неопределенной длины.
pdwDataLen
[in/out] Указатель на буфер, содержащий длину данных параметра. При вызове функции указанный параметр содержит число байтов в буфере pbData. После её выполнения параметр будет установлен числом байтов данных параметра, скопированных в буфер pbData. Если буфер, соответствующий pbData, недостаточно велик, чтобы в него копировать запрошенные данные, через функцию GetLastError() будет возвращен код ошибки ERROR_MORE_DATA. В этом случае требуемый размер буфера возвращается в pdwDataLen. Если эта функция завершается с кодом ошибки, отличным от ERROR_MORE_DATA, в этом параметре возвращается ноль.
dwFlags
[in] Значения флагов. Параметр зарезервирован для будущего использования и должен быть нулевым.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
ERROR_MORE_DATA | Размер буфера pbData недостаточен для копирования затребованных данных.
NTE_BAD_FLAGS | Параметр dwFlags имеет ненулевое значение.
NTE_BAD_TYPE | Параметр dwParam передаёт неизвестное значение параметра.
NTE_BAD_KEY | Дескриптор ключа ошибочен.
NTE_PERM | Попытка чтения ключевых параметров, когда право чтения криптопровайдером не представлено.
SCARD_E_NO_SUCH_CERTIFICATE | При попытке получения сертификата, когда сертификат отсутствует.

Примечания

Синхропосылка ключа для шифрования по алгоритму ГОСТ 28147-89 вырабатывается криптопровайдером автоматически с установкой типа ключа CALG28147 (сессионный ключ). Эту синхропосылку рекомендуется получить на передающем конце из ключа с помощью функции CPCGetKeyParam() для значения pvParam KP_IV. На приёмном конце значение синхропосылки устанавливается на ключ функцией CPCSetKeyParam() при значении pvParam KP_IV. Если требуется задание синхропосылки из приложения, то ее рекомендуется вырабатывать с помощью функции CPCGenRandom(). Использовать в системе другие алгоритмы образования синхропосылок можно только по согласованию с разработчиком криптопровайдера.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CPCSetKeyParam() ,CPGetKeyParam в MS CSP World Wide Web link ,CryptGetKeyParam в MS CryptoAPI 2.0 World Wide Web link


CPCGetUserKey

Функция CPCGetUserKey() возвращает дескриптор одной из долговременных ключевых пар в ключевом контейнере.

DWORD CPCAPI CPCGetUserKey(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  DWORD dwKeySpec,
  HCRYPTKEY * phUserKey
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера.
Получается при помощи функции CPCAcquireContext().
dwKeySpec
[in] Спецификация возвращаемого ключа. Следующие типы ключевых пар и ключей определены в настоящее время:
Значение | Описание
AT_KEYEXCHANGE | Ключевая пара обмена
AT_SIGNATURE | Ключевая пара цифровой подписи
AT_UECSYMMETRICKEY | Симметричный ключ - мастерключ для систем аутентификации карт
phUserKey
[out] Адрес, по которому функция копирует дескриптор ключа.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_NO_KEY | Ключ, указанный dwKeySpec параметром, не существует.
NTE_BAD_TYPE | Значение параметра dwKeySpec неизвестно.
SCARD_W_CANCELLED_BY_USER | Пользователь прервал операцию нажатием клавиши Cancel
SCARD_W_WRONG_CHV | Пользователь ввёл неправильный пароль или пароль, установленный функцией SetProvParam(), неправильный
SCARD_E_INVALID_CHV | Пользователь ввёл пароль с нарушением формата или пароль, установленный функцией SetProvParam(), имеет неправильный формат. Например, пароль имеет недопустимую длину или содержит недопустимые символы.
SCARD_W_CHV_BLOCKED | Ввод Pin-кода был заблокирован смарт-картой, т.к. исчерпалось количество попыток разрешенное картой для ввода.
NTE_SILENT_CONTEXT | Операция не может быть выполнена без пользовательского интерфейса.
SCARD_W_REMOVED_CARD | Носитель контейнера был удален из считывателя

Примечания

При перечислении ключей типа AT_UECSYMMETRICKEY производится считывание ключа из ключевого контейнера. В некоторых случаях это может приводить к вызову окна запроса пароля ключа.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CPCExportKey() ,CPCGenKey() ,CPGetUserKey в MS CSP World Wide Web link ,CryptGetUserKey в MS CryptoAPI 2.0 World Wide Web link


CPCImportKey

Функция CPCImportKey() используется для импорта криптографического ключа из ключевого блоба в контейнер криптопровайдера, для диверсификации ключа с использованием данных, передаваемых через ключевой блоб в соответствии с RFC 4357, п. 7., а так же для диверсификации ключа в соответствии с алгоритмами, описанным в п. 4.4, 4.5 рекомендаций по стандартизации "Криптографические алгоритмы, сопутствующие применению алгоритмов электронной цифровой подписи и функции хэширования".

DWORD CPCAPI CPCImportKey(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  CONST BYTE * pbData,
  DWORD dwDataLen,
  HCRYPTKEY hImpKey,
  DWORD dwFlags,
  HCRYPTKEY * phKey
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
pbData
[in] Указатель на буфер, содержащий ключевой блоб, произведенный с иcпользованием функции CPExportKey() данным или другим криптопровайдером, функционирующим на удалённом компьютере, или блоб диверсификации, используемый для диверсификации ключа на основе данных, передаваемых через блоб в соответствии с RFC 4357, п. 7. или в соответствии с п. 4.4, 4.5 рекомендаций по стандартизации "Криптографические алгоритмы, сопутствующие применению алгоритмов электронной цифровой подписи и функции хэширования"
dwDataLen
[in] Длина ключевого блоба в байтах.
hImpKey
[in] Дескриптор ключа, на котором осуществляется снятие криптографической защиты импортируемого ключа. Значение этого параметра должно соответствовать значению hExpKey, определённому для функции CPCExportKey() при создании ключевого блоба. После зашифрования ключевого блоба на сессионном ключе этот параметр содержит дескриптор на сессионный ключ. Если ключевой блоб не зашифрован (например, PUBLICKEYBLOB), этот параметр не используется и должен быть равен нулю. В алгоритме диверсификации hImpKey - исходный ключ, из которого вырабатываются диверсифицированные ключи.
dwFlags
[in] Значение флага. Этот параметр в настоящее время используется только, когда ключевая пара (закрытый/открытый ключи) импортируется в криптопровайдер (в форме PRIVATEKEYBLOB). Если импортируемый ключ будет заново экспортироваться, в этот параметр помещается флаг CRYPT_EXPORTABLE. Если этот флаг не используется, вызовы функции CryptExportKey в MS CryptoAPI 2.0 World Wide Web link с дескриптором ключа будут терпеть неудачу.
phKey
[out] Адрес, по которому функция копирует дескриптор импортированного либо диверсифицированного ключа. В алгоритме диверсификации ключ phKey наследует параметры ключа hImpKey: KP_OID, KP_MODE, KP_MIXMODE, KP_PADDING. При импорте ключей CALG_GR3410EL, CALG_DH_EL_SF, CALG_DH_GR3410_12_256_SF, CALG_GR3410_12_256, CALG_DH_GR3410_12_512_SF, CALG_GR3410_12_512, CALG_UECSYMMETRIC, если ключевой контейнер не содержит соответствующих ключей AT_SIGNATURE, AT_KEYEXCHANGE, AT_UECSYMMETRICKEY, импортируемые ключи устанавливаются в ключевой контейнер

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_DATA | Не прошёл контроль целостности импортируемого ключевого блоба. Ошибочная длина блоба.
NTE_BAD_FLAGS | Параметр dwFlags содержит ошибочную величину.
NTE_BAD_KEY | Один или оба из ключей, указанных hKey и hImpKey, не действительны. Байты в элементах заголовка ключевого блоба типа WORD, DWORD имеют обратный порядок по отношению к данной платформе.
NTE_BAD_TYPE | Тип ключевого блоба не поддерживается этим криптопровайдером и, возможно, ошибочен.
NTE_PERM | Попытка импорта ключа, когда право импорта криптопровайдером не предоставлено.
NTE_NO_MEMORY | Криптопровайдер во время операции исчерпал память.
NTE_FAIL | Нарушение целостности ключей в ОЗУ. см. Дополнительные параметры и определения .
SCARD_W_CANCELLED_BY_USER | Пользователь прервал операцию нажатием клавиши Cancel
SCARD_W_WRONG_CHV | Пользователь ввёл неправильный пароль или пароль, установленный функцией SetProvParam(), неправильный
SCARD_E_INVALID_CHV | Пользователь ввёл пароль с нарушением формата или пароль, установленный функцией SetProvParam(), имеет неправильный формат. Например, пароль имеет недопустимую длину или содержит недопустимые символы.
SCARD_W_CHV_BLOCKED | Ввод Pin-кода был заблокирован смарт-картой, т.к. исчерпалось количество попыток, разрешенное картой для ввода.
NTE_TOKEN_KEYSET_STORAGE_FULL | Недостаточно места на носителе для сохранения информации.
NTE_SILENT_CONTEXT | Операция не может быть выполнена без пользовательского интерфейса.
SCARD_W_REMOVED_CARD | Носитель контейнера был удален из считывателя
NTE_EXISTS | Попытка импортировать ключ в случае, когда ключ соответствующего типа в контейнере существует.
ERROR_FUNCTION_FAILED | нет лицензии, дающей право на выполнение функции импорта ключа

Примечания

Обычно для согласования (экспорта/импорта) сессионного ключа применяют алгоритм Диффи-Хеллмана. В этом случае ключ парной связи (ключ экспорта/импорта сессионного ключа) порождается операцией импорта открытого ключа получателя (отправителя) на ключевой паре отправителя (получателя). Следует учитывать, что при использовании эфемерных ключей аутентификация пользователей не обеспечивается. Для импорта сессионного ключа следует выполнить следующие шаги:

  • Импорт блоба открытого ключа отправителя (CRYPT_PUBLICKEYBLOB ) на своей ключевой паре;
  • Импорт сессионого ключа (CRYPT_SIMPLEBLOB ) на ключе парной связи.

Для ключей 2012 в качестве алгоритма согласования сессионного ключа используется алгоритм VKO GOST R 34.10-2012-256 (на основе функции хэширования ГОСТ Р 34.11-2012-256), параметр KP_CIPHEROID результирующего ключа принимает значение, установленное в параметрах импортируемого открытого ключа (если не указано, то "1.2.643.7.1.2.5.1.1", вариант ТК26 Z). Режимы шифрования, преобразования ключа и дополнения открытого текста до кратности блока для получаемого ключа устанавливаются аналогично вновь создаваемому ключу (см. CPCSetKeyParam()).

Для ключей 2001 используется алгоритм VKO GOST R 34.10-2001 (на основе функции хэширования ГОСТ Р 34.11-94). При использовании данного алгоритма с долговременным ключом параметр KP_CIPHEROID полученного ключа принимает oid параметров шифрования, установленный в соответствующем долговременному ключу контейнере; при использовании с эфемерным ключом параметр KP_CIPHEROID результирующего ключа принимает установленное для провайдера значение PP_CIPHEROID. Режимы шифрования, преобразования ключа и дополнения открытого текста до кратности блока для получаемого ключа устанавливаются аналогично вновь создаваемому ключу (см. CPCSetKeyParam()).

Однако, в ядре ОС отсутствует поддержка долговременных ключей. Поэтому ключ сессии (на файл или ассоциацию) или ключевая пара для ЭП обычно передаются из поддерживающего сервиса (демона). Для этого сначала вырабатывается совместный ключ (hDrvKey):

      ...
      // Инициализация работы с драйвером
      CPCGetProvParam(hCSP, hProv, PP_RANDOM, pbRandomBlobToDriver, cbRandomBlobToDriver);
      ...
      // Передать инициализатор ДСЧ (pbRandomBlobToDriver) в поддерживающий сервис и
      // получить от него случайную последовательность (pbRandomFromDriver).
      ...
      CPCCreateHash(hCSP, hProv, CALG_GR3411, 0, 0, &hDrvHash);
      CPCHashData(hCSP, hProv, hDrvHash, "DriverDaemon", sizeof("DriverDaemon"), 0);
      CPCHashData(hCSP, hProv, hDrvHash, pbRandomBlobToDriver, cbRandomBlobToDriver, 0);
      CPCHashData(hCSP, hProv, hDrvHash, pbRandomFromDriver, cbRandomFromDriver, 0);
      CPCDeriveKey(hCSP, hProv, hDrvHash, &hDrvKey);
      CPCDestroyHash(hCSP, hProv, hDrvHash);
      ...

На этом ключе сервис может экспортировать ключевую пару для подписи:

      ...
      // Получение дескриптора ключевой пары:
      CPCGetUserKey(hCSP, hProv, AT_SIGNATURE, &hUserKey);

      // Подготовка ключевой пары для передачи в драйвер:
      CPCExportKey(hCSP, hProv, hUserKey, hDrvKey, PRIVATEKEYBLOB, 0, pbPrivateKeyForDriver, &cbPrivateKeyForDriver);
      ...
      // Передать pbPrivateKeyForDriver в драйвер
      ...

Аналогичным образом можно экспортировать ключ сессии:

      ...
      // Импорт ключа сессии (файла, ассоциации) от отправителя:
      CPCImportKey(hCSP, hProv, pbSenderPublicKey, cbSenderPublicKey, hUserKey, 0, &hExchKey);
      ALG_ID ke_alg = CALG_PRO_EXPORT;
      CPCSetKeyParam(hCSP, hProv, hExchKey, KP_ALGID, (LPBYTE)&ke_alg, 0);
      CPCImportKey(hCSP, hProv, pbSessionKeyFromSender, &cbSessionKeyFromSender, hExchKey, 0, &hSessionKey);

      // Подготовка его для передачи в драйвер
      CPCExportKey(hCSP, hProv, hSessionKey, hDrvKey, SIMPLEBLOB, 0, pbSessionKeyForDriver, &cbSessionKeyForDriver);
      ...
      // Передать pbSessionKeyForDriver в драйвер
      ...

На основе ключа сессии можно получить ключи блоков (пакетов) с помощью CPCGenKey(), CPCDeriveKey() или алгоритма диверсификации ключа в функции CPCImportKey() (CRYPT_DIVERSBLOB ).

      ...
      // Инициализация работы с демоном (сервисом)
      ...
      // Получить инициализатор ДСЧ (pbRandomBlobFromDaemon) в драйвер.
      ...
      CPCSetProvParam(hCSP, hProv, PP_RANDOM, pbRandomBlobFromDaemon);
      CPCGenRandom(hCSP, hProv, cbRandomToDaemon, pbRandomToDaemon);
      CPCCreateHash(hCSP, hProv, CALG_GR3411, 0, 0, &hDmnHash);
      CPCHashData(hCSP, hProv, hDmnHash, "DriverDaemon", sizeof("DriverDaemon"), 0);
      CPCHashData(hCSP, hProv, hDmnHash, pbRandomBlobFromDaemon, cbRandomBlobFromDaemon, 0);
      CPCHashData(hCSP, hProv, hDmnHash, pbRandomToDaemon, cbRandomToDaemon, 0);
      CPCDeriveKey(hCSP, hProv, hDmnHash, &hDmnKey);
      CPCDestroyHash(hCSP, hProv, hDmnHash);
      ...
      // Передать случайную последовательность демону (сервису).
      ...
      // Получить pbSessionKeyFromDaemon из демона (сервиса)
      ...
      CPCImportKey(hCSP, hProv, pbSessionKeyFromDaemon, &cbSessionKeyFromDaemon, hDmnKey, 0, &hSessionKey);
      ...
      // Вариант получения ключа блока (пакета) на основе ключа сесcии (файла, ассоциации)
      // с помощью CPCGenKey.
      CPCImportKey(hCSP, hProv, pbBlkBlob, cbBlkBlob, hSessionKey, 0, &hBlkKey);
      ...
      // Вариант получения ключа блока (пакета) на основе ключа сесcии (файла, ассоциации)
      // с помощью CPCDeriveKey.
      // bBlockNumber - указатель на байтовую последовательность, диверсифицирующая ключ.
      CPCCreateHash(hCSP, hProv, CALG_GR3411, 0, 0, &hHash);
      CPCHashData(hCSP, hProv, hHash, "DeriveBlkKey", sizeof("DeriveBlkKey"), 0);
      CPCHashSessionKey(hCSP, hProv, hHash, hSessionKey, 0);
      CPCHashData(hCSP, hProv, hHash, bBlockNumber, sizeof(dwBlockNumber), 0);
      CPCDeriveKey(hCSP, hProv, CALG_G28147, hHash, 0, &hBlkKey);
      CPCDestroyHash(hCSP, hProv, hHash);
      ...
      // Пример получения ключа блока (пакета) на основе ключа сесcии (файла, ассоциации)
      // с помощью возможности диверсификации ключа функцией CPCImportKey в соответствии с
      // алгоритмом, описанным в п.7 RFC 4357.
      // bBlockNumber - байтовая последовательность, диверсифицирующая ключ.
      Blob.DiversBlobHeader.BlobHeader.bType = DIVERSKEYBLOB;
      Blob.DiversBlobHeader.BlobHeader.bVersion = 0x20;
      Blob.DiversBlobHeader.BlobHeader.reserverd = 0;
      Blob.DiversBlobHeader.BlobHeader.aiKeyAlg = CALG_G28147;
      Blob.DiversBlobHeader.aiDiversAlgId = CALG_PRO_DIVERS;
      Blob.DiversBlobHeader.dwDiversMagic = 0x31564944;
      Blob.DiversBlobHeader.cbDiversData = sizeof(bBlockNumber);
      CopyMemory((LPBYTE)Blob.bDiversData,bBlockNumber,sizeof(bBlockNumber));
      CPCImportKey(hCSP, hProv, &Blob, sizeof(Blob), hSessionKey, 0, &hBlkKey);
      // Диверсификация в соответствии с алгоритмом KDF_GOSTR3411_2012_256
      // проводится аналогично с тем отличием, что в поле aiDiversAlgId
      // записывается константа CALG_PRO12_DIVERS

С помощью этой же функции в режиме диверсификации ключа (CRYPT_KDF_TREE_DIVERSBLOB ) можно создавать ключи блоков (пакетов) на основе процедуры диверсификации КриптоПро CSP, предусматривающей возможность выработки нескольких ключей.

      ...
      // Пример выработки нескольких ключей на основе ключа диверсификации
      // с помощью алгоритма CALG_KDF_TREE_GOSTR3411_2012_256, описанного
      // в п.4.5 рекомендаций по стандартизации "Криптографические алгоритмы,
      // сопутствующие применению алгоритмов электронной цифровой подписи и функции хэширования"
      // bSeedData - байтовая последовательность Seed, диверсифицирующая ключ.
      // bLabelData - байтовая последовательность Label, диверсифицирующая ключ.
      dwBlobLen = sizeof(CRYPT_KDF_TREE_DIVERSBLOB_HEADER) + sizeof(CRYPT_KDF_TREE_DIVERS_INFO) +
          sizeof(bSeedData) + sizeof(bLabelData);
      DiversBlob.KdfTreeBlobHeader.BlobHeader.aiKeyAlg = CALG_G28147;
      DiversBlob.KdfTreeBlobHeader.BlobHeader.bType = KDF_TREE_DIVERSBLOB;
      DiversBlob.KdfTreeBlobHeader.BlobHeader.bVersion = BLOB_VERSION;
      DiversBlob.KdfTreeBlobHeader.BlobHeader.reserved = 0;
      DiversBlob.KdfTreeBlobHeader.aiDiversAlgId = CALG_KDF_TREE_GOSTR3411_2012_256;
      DiversBlob.KdfTreeBlobHeader.dwIterNum = 1;
      DiversBlob.KdfTreeDiversInfo.dwLabelLen = sizeof(bLabelData);
      DiversBlob.KdfTreeDiversInfo.dwSeedLen = sizeof(bSeedData);
      DiversBlob.KdfTreeDiversInfo.L_value = 1024;
      DiversBlob.KdfTreeDiversInfo.R_value = 2;
      CopyMemory((LPBYTE)DiversBlob.bDiversData, bSeedData, sizeof(bSeedData));
      CopyMemory((LPBYTE)DiversBlob.bDiversData + sizeof(bSeedData), bLabelData, sizeof(bLabelData));
      // Первичный вызов с передачей всех параметров диверсификации
      CPCImportKey(hCSP, hProv, &DiversBlob, dwBlobLen, hSessionKey, 0, &hDivKey[0]);
      // Для последующих вызовов достаточно передачи хэдера с нужным номером ключа
      // Вызовы с различными номерами результирующих ключей могут идти не по порядку
      DiversBlob.KdfTreeBlobHeader.dwIterNum = 3;
      CPCImportKey(hCSP, hProv, &DiversBlob.KdfTreeBlobHeader,
          sizeof(CRYPT_KDF_TREE_DIVERSBLOB_HEADER), hSessionKey, 0, &hDivKey[1]);
      ...

В случае импорта SIMPLEBLOB, PUBLICKEYBLOB или DIVERSKEYBLOB (при использовании алгоритма диверсификации CALG_PRO_DIVERS) разрешается многопоточная работа функции. При импорте SIMPLEBLOB необходимо передавать флаг CP_CRYPT_NOKEYWLOCK, при этом ключ hImpKey блокируется только на чтение. Корректность работы функции и целостность ключа импорта гарантируются криптопровайдером.

В случае импорта SIMPLEBLOB набор узлов замены устанавливается в соответствии с указанным в блобе. Режимы шифрования, преобразования ключа и дополнения открытого текста до кратности блока для получаемого ключа устанавливаются аналогично вновь создаваемому ключу (см. CPCSetKeyParam()).

В случае импорта OPAQUEKEYBLOB набор узлов замены, режимы шифрования, преобразования ключа и дополнения открытого текста до кратности блока устанавливаются в соответствии с параметрами, указанными в блобе.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CRYPT_PRIVATEKEYBLOB ,CRYPT_PUBLICKEYBLOB ,CRYPT_SIMPLEBLOB ,CRYPT_OPAQUEBLOB ,CRYPT_DIVERSBLOB ,CPCExportKey() ,CPCGenKey() ,CPImportKey в MS CSP World Wide Web link ,CryptImportKey в MS CryptoAPI 2.0 World Wide Web link


CPCSetKeyParam

Функция CPCSetKeyParam() устанавливает параметры ключа.

DWORD CPCAPI CPCSetKeyParam(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  HCRYPTKEY hKey,
  DWORD dwParam,
  BYTE * pbData,
  DWORD dwFlags
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
hKey
[in] Дескриптор ключа, параметры которого устанавливаются.
dwParam
[in] Параметр, принимающий следующие возможные значения:
Значение dwParam | Содержимое буфера pbData
KP_ALGID Идентификатор алгоритма ключа (ALG_ID), соответствующий данному ключу. Передаётся функции через буфер pbData. Возможо установить значение CALG_G28147 для ключей класса ALG_CLASS_DATA_ENCRYPT (сессионных ключей).
ALG_ID | Описание
CALG_G28147 | Ключ шифрования и/или имитозащиты данных по ГОСТ 28147-89. Впоследствии этот ключ можно пометить как ключ для импорта/экспорта с помощью функции CPCSetKeyParam().
CALG_SYMMETRIC_512 | Ключ парной связи по Диффи-Хеллману с длиной выхода 512 бит.
CALG_PRO_EXPORT | Ключ экспорта/импорта ключей типа CALG_G28147 для хранения на диске или передачи по каналу связи.
CALG_PRO12_EXPORT | Ключ защищённого экспорта по рекомендациям ТК26 (обязателен для использования с ключами ГОСТ Р 34.10-2012).
CALG_SIMPLE_EXPORT Ключ экспорта/импорта ключей типа CALG_G28147 по ГОСТ 28147-89 в режиме простой замены для хранения на ключевом носителе.

Использование CALG_SIMPLE_EXPORT для ключей CALG_G28147, переданных в канале связи, возможно только в случае обеспечения строгой однократности операции импорта ключа принимающей стороной и гарантированной случайности получения ключа передающей стороной.

Использование CALG_SIMPLE_EXPORT при экспорте/импорте ключей CALG_TLS1_MASTER происходит с усложнением ключа аналогичным CALG_PRO_EXPORT.

Недопустимо использование CALG_SIMPLE_EXPORT для экспорта/импорта ключей с целью их хранения на диске.
CALG_TLS1_MASTER | Ключ для реализации протокола TLS.
CALG_TLS1_MAC_KEY | Ключ для реализации протокола TLS.
CALG_TLS1_ENC_KEY | Ключ для реализации протокола TLS.
Устанавливает значения CALG_EKE_CIPHER на ключ CALG_PRO_AGREEDKEY_DH. Так же на ключ CALG_EKE_CIPHER может быть установлен тип CALG_PRO_AGREEDKEY_DH. Специфика протокола ООО "КРИПТО-ПРО" взаимодействия с функциональным ключевым носителем.
KP_IV | Устанавливает начальное значение вектора инициализации (IV или синхропосылки) алгоритма шифрования. Начальное значение синхропосылки по умолчанию (после создания, дублирования и или завершения операции шифрования) - случайное. Последовательность байтов, содержащая IV, передаётся функции через буфер pbData. Если ключ использовался в вызове CPCEncrypt() или CPCDecrypt() с параметром Final = FALSE, то изменение данного параметра невозможно до вызова соответствующей функции с параметром Final = TRUE.
KP_IV_BLOB | Устанавливает начальное значение вектора инициализации (IV или синхропосылки) для алгоритма VKO GOST R 34.10-2012-256. Начальное значение синхропосылки по умолчанию - случайное. Данные передаются в форме BLOB структуры, где член структуры pbData указывает на данные, а cbData передаёт длину данных.
KP_CERTIFICATE | Установка сертификата в контейнер (на носитель). Сертификат должен соответствовать ключу в контейнере.
KP_PADDING Способ дополнения. Величина DWORD, содержащая метод дополнения, используемый шифром ключа, передаётся функции через буфер pbData. В настоящее время определены следующие способы дополнения:
  • PKCS5_PADDING - PKCS#5.(См ПРИМЕЧАНИЕ в данном разделе и ПРИМЕЧАНИЕ к CryptSetKeyParam в MS CryptoAPI 2.0 World Wide Web link )
  • ZERO_PADDING - дополнение нулевыми байтами,
  • RANDOM_PADDING - дополнение случайными байтами,
  • ISO10126_PADDING - дополнение в соответствии с ISO 10126,
  • ANSI_X923_PADDING - дополнение в соответствии с ANSI X.923.
При первоначальной выработке ключа по умолчанию устанавливается значение PKCS5_PADDING.
KP_MODE

Режим шифра. Переменная типа DWORD. Передаётся функции через буфер pbData. Если ключ использовался в вызове CPCEncrypt() или CPCDecrypt() с параметром Final = FALSE, то изменение данного параметра невозможно до вызова соответствующей функции с параметром Final = TRUE. В следующем списке приведены режимы шифрования для ключей CALG_G28147 класса ALG_CLASS_DATA_ENCRYPT, доступные в настоящее время:

  • CRYPT_MODE_ECB - блочный шифр простой замены ГОСТ 28147-89;
  • CRYPT_MODE_CNT - шифрование гаммированием ГОСТ 28147-89;
  • CRYPT_MODE_CFB - шифрование гаммированием с обратной связью ГОСТ 28147-89;
  • CRYPT_MODE_CBCRFC4357 - блочный шифр с обратной связью на базе ГОСТ 28147-89, согласно RFC 4357;
  • CRYPT_MODE_CBCSTRICT - блочный шифр с обратной связью на базе ГОСТ 28147-89, шифртекст блока всегда является IV для следующего. Рекомендуется для использования только для обеспечения совместимости с существующими продуктами.
При первоначальной выработке ключа по умолчанию устанавливается значение CRYPT_MODE_CFB.

Для ключей CALG_EKE_CIPHER доступны режимы шифрования:

  • CRYPT_MODE_EKEXOR - одноразовый шифр гаммирования по модулю 2, в данном режиме вычисляется значение открытого ключа, соответствующего ключу CALG_PRO_AGREEDKEY_DH и координата X ключа накладывается по модулю 2 на данные, данные длиной 32 байта должны подаваться одним блоком;
  • CRYPT_MODE_EKEECADD - одноразовый шифр гаммирования в группе точек эллиптической кривой, в данном режиме вычисляется значение открытого ключа, соответсвующего ключу CALG_PRO_AGREEDKEY_DH и ключ накладывается на данные аддитивно в группе точек эллиптической кривой, данные должны быть блобом открытого ключа длиной 100 байт и подаваться одним блоком.

KP_MODE_BITS | Глубина обратной связи. Переменная типа DWORD. Значение этой величины равно 64, что соответствует режиму гаммирования с обратной связью ГОСТ 28147-89.
KP_MIXMODE | Дополнительный параметр ключа. Устанавливает режим преобразования ключа после зашифрования каждых 1024 байт информации. Режим преобразования ключа (CRYPT_PROMIX_MODE) установлен по умолчанию. Выйти из этого режима можно, если для этого параметра в pbData будет установлено CRYPT_SIMPLEMIX_MODE. Если в pbData установлено CRYPT_PROMIX_MODE, устанавливается режим преобразования ключа. Размер pbData - 4 байта. Может быть установлен для ключей типа CALG_G28147. Если ключ использовался в вызове CPCEncrypt() или CPCDecrypt() с параметром Final = FALSE, то изменение данного параметра невозможно до вызова соответствующей функции с параметром Final = TRUE.
KP_MIXSTART | Осуществляет диверсификацию ключа по алгоритму CALG_PRO_DIVERS. Через параметр pbData передаётся блоб диверсификации ключа в форме CRYPT_DATA_BLOB, см. CPCImportKey(). Допускается многократный вызов с различными параметрами диверсификации.
KP_CIPHEROID | Идентификатор узла замены. Строка, заканчивающаяся нулем. При первоначальной выработке ключа по умолчанию устанавливается в соответствии с параметрами, указанными в панели криптопровайдера. Для провайдера PROV_GOST_2001_DH в панели по умолчанию указан набор "ГОСТ 28147-89, параметры по умолчанию" (szOID_Gost28147_89_CryptoPro_A_ParamSet, 1.2.643.2.2.31.1), для PROV_GOST_2012_256 и PROV_GOST_2012_512 - набор "ГОСТ 28147-89, параметры шифрования ТК 26 Z" (szOID_Gost28147_89_TC26_Z_ParamSet, 1.2.643.7.1.2.5.1.1).
KP_DHOID | Идентификатор параметров ключа ГОСТ Р 34.10-2001, применяемых в алгоритме Диффи-Хеллмана. Строка, заканчивающаяся нулем. Начиная с версии 3.6 допускается устанавливать идентификаторы подписи. Необходимо устанавливать глобальным параметром PP_DHOID до генерации ключа.
KP_HASHOID | Идентификатор функции хэширования. Строка, заканчивающаяся нулем. Необходимо устанавливать глобальным параметром PP_HASHOID до генерации ключа.
KP_CLIENT_RANDOM | Идентификатор величины ClientRandom, используемой с ключами типа CALG_TLS1_MASTER. Размер ClientRandom - 32 байта. Используется при преобразовании premaster_secret в master_secret и при генерации ключевой информации в момент создания хэша CALG_TLS1_MASTER_HASH.
KP_SERVER_RANDOM | Идентификатор величины ServerRandom, используемой с ключами типа CALG_TLS1_MASTER.Размер ServerRandom - 32 байта. Используется при преобразовании premaster_secret в master_secret и при генерации ключевой информации в момент создания хэша CALG_TLS1_MASTER_HASH.
KP_PREHASH

Идентификатор, используемый ключами типа CALG_TLS1_MASTER. Предварительно требуется установить KP_CLIENT_RANDOM и KP_SERVER_RANDOM. Вызов функции преобразует premaster_secret в master_secret.

KP_X | Закрытый ключ в ключевой паре. 32 байта для ключей ГОСТ Р 34.10-2012 длины 256 бит (ГОСТ Р 34.10-2001) и 64 байта для ключей ГОСТ Р 34.10-2012 длины 512 бит в форме little endian. Данные передаются в форме BLOB структуры, где член структуры pbData указывает на данные, а cbData передаёт длину данных.
KP_MULX | Для произвольной ключевой пары осуществляет умножение закрытого и открытого ключей на значение передаваемого параметра pbData. Для ключа CALG_PRO_AGREEDKEY_DH осуществляет умножение закрытого ключа на значение передаваемого параметра pbData. Данные передаются в форме BLOB структуры, где член структуры pbData указавает на данные - 32 байта для ключей ГОСТ Р 34.10-2012 длины 256 бит (ГОСТ Р 34.10-2001) и 64 байта для ключей ГОСТ Р 34.10-2012 длины 512 бит в форме little endian, а cbData передаёт длину данных.
KP_MULX_INVERS | Аналогично KP_MULX осуществляет умножение на величину, обратную к величине, передаваемой в параметре pbData.
KP_ADDX | Для закрытого ключа осуществляет сложение по модулю q значения ключа и значения смещения, передаваемого через параметр pbData. Данные передаются в форме BLOB структуры, где поле pbData указывает на данные - смещение, а cbData передаёт длину данных.
KP_SUBX | Для открытого ключа осуществляет вычитание по модулю q из значения ключа значения смещения, передаваемого через параметр pbData. Данные передаются в форме BLOB структуры, где поле pbData указывает на данные - смещение, а cbData передаёт длину данных.
KP_ECADD | Для открытого ключа осуществляет сложение в группе точек эллиптической кривой открытого ключа и значения блоба открытого ключа, передаваемого через параметр pbData. Данные передаются в форме BLOB структуры, где поле pbData указывает на данные - блоб открытого ключа, а cbData передаёт длину данных.
KP_ECSUB | Для открытого ключа осуществляет вычитание в группе точек эллиптической кривой открытого из ключа значение блоба открытого ключа, передаваемого через параметр pbData. Данные передаются в форме BLOB структуры, где поле pbData указывает на данные - блоб открытого ключа, а cbData передаёт длину данных.
KP_DEMASKPUBLIC | Устанавливает открытый ключ на ключ CALG_PRO_AGREEDKEY_DH, что обеспечивает расшифрование ключа в алгоритме выработки ключа обмена с использованием функционального ключевого носителя. Специфика протокола ООО "КРИПТО-ПРО" взаимодействия с функциональным ключевым носителем.
KP_SYNCRO | Устанавливает значение синхропосылки на ключ пользователя. Ключ должен быть создан в контексте с флагом CRYPT_TOKEN_SHARED. Данные передаются в форме BLOB структуры, где pbData указывает на данные – 32 байта синхропосылки, а cbData передаёт длину данных. Специфика протокола ООО "КРИПТО-ПРО" взаимодействия с функциональным ключевым носителем.
KP_UEC_DERIVE_COUNTER | Для ключа типа AT_UECSYMMETRICKEY устанавливает значение счетчика ключей, полученных диверсификацией данного. Переменная типа DWORD.
pbData
[in] Указатель на буфер данных параметра. При вызове функции буфер содержит, соответствующие значению параметра в dwParam. Формат данных зависит от типа параметра.
dwFlags
[in] Значения флагов. Параметр зарезервирован для будущего использования и должен быть нулевым.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_FLAGS | Параметр dwFlags имеет ненулевое значение.
NTE_BAD_TYPE | Параметр dwParam передаёт неизвестное значение параметра.
NTE_BAD_KEY | Дескриптор ключа ошибочен.
NTE_BAD_KEY_STATE | Указанный параметр временно не может быть изменен.
NTE_PERM | Попытка чтения ключевых параметров, когда право чтения криптопровайдером не предоставлено.
NTE_FIXEDPARAMETER | Была произведена попытка установить параметры, постоянные для данного криптопровайдера.
NTE_BAD_DATA | Неправильные данные в буфере pbData.

Примечания

ДОПОЛНЕНИЕ PKCS #5 Эта схема дополнения определена RSA Data Security, Inc. и описана в "Public-Key Cryptography Standards (PKCS)", PKCS #5, раздел 6.2. При использовании данной схемы последовательность всегда дополняется знаками, даже в случае, когда её длина кратна длине блока шифрования. Последовательность дополнения состоит из байтов, каждый из которых равен числу дополнительных байтов. Если дополняется последовательность из 24 бит, последовательность дополнения равна “05 05 05 05 05”. Если дополняются 64 бита, последовательность дополнения равна “08 08 08 08 08 08 08 08”. При расшифровании, если расширение блока удовлетворяет условиям дополнения PKCS #5, функция CPCDecrypt() в переменной pdwDataLen, возвращает истинное значение длины открытого текста. Если расширение блока не удовлетворяет условиям дополнения PKCS #5, функция CPCDecrypt() возвращает ошибку NTE_BAD_DATA, а в переменной pdwDataLen значение длины шифрованного текста. ДОПОЛНЕНИЕ ZERO При использовании данной схемы, последовательность дополняется нулевыми байтами до наименьшей длины, кратной длине блока шифрования. ДОПОЛНЕНИЕ RANDOM При использовании данной схемы, последовательность дополняется случайными байтами до наименьшей длины, кратной длине блока шифрования. ДОПОЛНЕНИЕ ISO 10126 Эта схема определена стандартом ISO 10126. При использовании данной схемы последовательность всегда дополняется знаками, даже если её длина кратна длине блока шифрования. Последовательность дополнения кроме последнего байта состоит из случайных байтов, в последнем байте указывается общая длина дополнения в байтах. Если дополняется последовательность длиной 24 бита, то последовательность дополнения может быть следующей: "6F 43 3D B2 05", где первые 4 байта выбраны случайно. Если дополняются 64 бита, последовательность дополнения может быть следующей: "B6 87 2D 4A 40 A1 F9 08", где первые семь байт выбраны случайно. При расшифровании, если расширение блока удовлетворяет условиям дополнения ISO 10126, функция CPCDecrypt() в переменной pdwDataLen, возвращает истинное значение длины открытого текста. Если расширение блока не удовлетворяет условиям дополнения ISO 10126, функция CPCDecrypt() возвращает ошибку NTE_BAD_DATA, а в переменной pdwDataLen значение длины шифрованного текста. ДОПОЛНЕНИЕ ANSI X.923 Эта схема определена стандартом ANSI X.923. При использовании данной схемы последовательность всегда дополняется знаками, даже если её длина кратна длине блока шифрования. Последовательность дополнения кроме последнего байта состоит из нулевых байтов, в последнем байте указывается общая длина дополнения в байтах. Если дополняется последовательность длиной 24 бита, то последовательность дополнения является следующей: "00 00 00 00 05". Если дополняются 64 бита, последовательность дополнения является следующей: "00 00 00 00 00 00 00 08". При расшифровании, если расширение блока удовлетворяет условиям дополнения ANSI X.923, функция CPCDecrypt() в переменной pdwDataLen, возвращает истинное значение длины открытого текста. Если расширение блока не удовлетворяет условиям дополнения ANSI X.923, функция CPCDecrypt() возвращает ошибку NTE_BAD_DATA, а в переменной pdwDataLen значение длины шифрованного текста.

РЕЖИМ CRYPT_MODE_ECB В соответствии с требованиями ГОСТ 28147-89 режим шифрования простой заменой CRYPT_MODE_ECB может использоваться только для шифрования ключевой информации.

Значение параметра KP_CIPHEROID, установленное на долговременный ключ, сохраняется только в текущем контексте. После вызова функции CPCReleaseContext() при повторном открытии контейнера и обращении к ключу данный параметр примет установленное в контейнере значение.

Значения параметров KP_MODE, KP_MIXMODE, KP_CIPHEROID и KP_PADDING, устанавливаемые по умолчанию во вновь создаваемый симметричный ключ операциями CPCImportKey(), CPCDuplicateKey() и CPCDeriveKey(), указаны в соответствующих разделах.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CPCGenKey() ,CPCGetKeyParam() ,CPSetKeyParam в MS CSP World Wide Web link ,CryptSetKeyParam в MS CryptoAPI 2.0 World Wide Web link


Функции шифрования/расшифрования данных

Функции шифрования/расшифрования данных предназначены для выполнения операций, шифрования и расшифрования данных.

Функции | Описание
CPCEncrypt | Функция CPCEncrypt() производит зашифрование данных. Одновременно может быть произведено их хэширование.
CPCDecrypt | Функция CPCDecrypt() расшифровывает данные, предварительно зашифрованные функцией CPCEncrypt(). Одновременно может быть произведено хэширование данных.


CPCEncrypt

Функция CPCEncrypt() производит зашифрование данных. Одновременно может быть произведено их хэширование.

DWORD CPCAPI CPCEncrypt(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  HCRYPTKEY hKey,
  HCRYPTHASH hHash,
  BOOL Final,
  DWORD dwFlags,
  BYTE * pbData,
  DWORD * pdwDataLen,
  DWORD dwBufLen
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
hKey
[in] Дескриптор ключа сессии, используемого для зашифрования данных. Недопустимо использование одного ключа в многопоточной обработке. Для организации многопоточной обработки необходимо размножать ключ с использованием функции CPCDuplicateKey().
hHash
[in] Дескриптор объекта функции хэширования. Если значение хэш-функции не вычисляется, этот параметр равен нулю.
Final
[in] Булева величина. Определяет, является ли переданный функции блок последним зашифрованным блоком данных. Она должна быть установлена TRUE, если это последний (или единственный) блок, и FALSE – в противном случае. При установке флага Final == TRUE, состояние усложнения ключа возвращается в первоначальное, а начальное значение синхропосылки устанавливается в случайное значение.
dwFlags
[in] Значения флагов. Параметр определяет способ обработки фрагмента данных в потоке. Нулевое значение соответствует шифрованию фрагмента данных потока, ненулевое значение соответствует обработке пакета данных. См. Шифрование и хэширование пакета .
pbData
[in/out] Если значение dwFlags нулевое, указатель на буфер, содержащий данные для зашифрования. Если установлен флаг CP_CRYPT_HASH_PACKET - указатель на буфер, содержащий пакет. См. Шифрование и хэширование пакета . Если установлены флаги CP_CRYPT_HASH_PACKET и CP_CRYPT_DATA_IOVEC, указатель на массив структур CSP_iovec, задающий пакет. См. Вектор ввода вывода . После шифрования данные помещаются в этот же буфер или передаются через массив структуру CSP_iovec. Если установлены флаги CP_CRYPT_HASH_PACKET и CP_CHP_MULTIPACKET, указатель на массив структур CSP_Multipacket_ENC, задающий массив пакетов для параллельной обработки на платформах, поддерживающих SIMD архитектуру SSSE3, AVX. См. Мультипакетная обработка .
pdwDataLen
[in/out] Если значение dwFlags нулевое, указатель на буфер, содержащий длину данных. Параметр dwDataLen определяет число байтов открытого текста в буфере pbData. Через этот параметр функция возвращает указатель на число байтов шифртекста, помещённого в буфер pbData. Если установлен флаг CP_CRYPT_HASH_PACKET, указатель на буфер, содержащий длину пакета. Если установлены флаги CP_CRYPT_HASH_PACKET и CP_CHP_STARTMIX, по указателю pdwDataLen передаётся и возвращается длина пакета включая блоб диверсификации ключей. Если установлены флаги CP_CRYPT_HASH_PACKET,CP_CRYPT_DATA_IOVEC и CP_CHP_STARTMIX, по указателю pdwDataLen передаётся и возвращается общая длина элементов вектора включая блоб диверсификации ключей (в этом варианте использования, блоб диверсификации должен передаваться отдельным первым элементом). Если установлены флаги CP_CRYPT_HASH_PACKET и CP_CHP_MULTIPACKET, указатель на количество структур CSP_Multipacket_ENC.
dwBufLen
[in] Если значение dwFlags нулевое, размер буфера pbData в байтах при условии возможности помещения в буфер зашифрованных данных. Если установлен флаг CP_CRYPT_HASH_PACKET, размер буфера pbData в байтах. Если установлены флаги CP_CRYPT_HASH_PACKET и CP_CRYPT_DATA_IOVEC, число элементов массива CSP_iovec. Если установлены флаги CP_CRYPT_HASH_PACKET, CP_CHP_MULTIPACKET, данный параметр должен иметь нулевое значение.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_ALGID | Ключ hKey определяет алгоритм, который данный криптопровайдер не поддерживает.
NTE_BAD_FLAGS | Величина dwFlags имеет некорректное значение, например, ненулевое значение при неустановленном флаге CP_CRYPT_HASH_PACKET.
NTE_BAD_DATA | Данные для зашифрования недействительны. В частности, в блочных режимах шифрования, если Final = FALSE, а длина шифруемого текста не кратна длине блока шифрования, возвращается данная ошибка. При шифровании пакета - ошибка формирования пакета.
NTE_BAD_KEY | Ключ недействителен. В частности, эта ошибка возвращается, если на ключе в состоянии CRYPT_SIMPLEMIX_MODE зашифровано более 4-x мегабайт текста.
NTE_BAD_HASH | Дескриптор хэша ошибочен.
NTE_BAD_LEN | Размер буфера недостаточен для помещения в него шифртекста. Если установлены флаги CP_CRYPT_HASH_PACKET,CP_CRYPT_DATA_IOVEC - длина, передаваемая в dwDataLen не совпадает с суммой длин координат IOVEC.
NTE_PERM | Право зашифрования на данном ключе криптопровайдером не предоставлено.
ERROR_FUNCTION_FAILED | нет лицензии, дающей право на выполнение функции шифрования
NTE_FAIL | Нарушение целостности ключей в ОЗУ. см. Дополнительные параметры и определения .

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CPCDecrypt() ,CPCGenKey() ,CPEncrypt в MS CSP World Wide Web link ,CryptEncrypt в MS CryptoAPI 2.0 World Wide Web link


CPCDecrypt

Функция CPCDecrypt() расшифровывает данные, предварительно зашифрованные функцией CPCEncrypt(). Одновременно может быть произведено хэширование данных.

DWORD CPCAPI CPCDecrypt(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  HCRYPTKEY hKey,
  HCRYPTHASH hHash,
  BOOL Final,
  DWORD dwFlags,
  BYTE * pbData,
  DWORD * pdwDataLen
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
hKey
[in] Дескриптор сессионного ключа, используемого для расшифрования данных.
hHash
[in] Дескриптор объекта хэширования. Если хэширование данных одновременно с их расшифрованием не требуется, этот параметр должен быть нулевым.
Final
[in] Булева величина. Определяет, является ли переданный функции блок последним расшифрованным блоком данных. Она должна быть установлена TRUE, если блок - последний или единственный, и FALSE – в противном случае. При установке флага Final == TRUE, состояние усложнения ключа возвращается в первоначальное, а начальное значение синхропосылки устанавливается в случайное значение.
dwFlags
[in] Значения флагов. Параметр определяет способ обработки фрагмента данных в потоке. Нулевое значение соответствует шифрованию фрагмента данных потока, ненулевое значение соответствует обработке пакета данных. См. Шифрование и хэширование пакета .
pbData
[in/out] Если значение dwFlags нулевое, указатель на буфер, содержащий данные для расшифрования. Если установлен флаг CP_CRYPT_HASH_PACKET указатель на буфер, содержащий пакет. См. Шифрование и хэширование пакета . Если установлены флаги CP_CRYPT_HASH_PACKET и CP_CRYPT_DATA_IOVEC, указатель на массив структур CSP_iovec, определяющий пакет. См. Вектор ввода вывода . После расшифрования открытые данные помещаются в этот же буфер или передаются через массив структур CSP_iovec. Если установлены флаги CP_CRYPT_HASH_PACKET и CP_CHP_MULTIPACKET, указатель на массив структур CSP_Multipacket_DEC, задающий массив пакетов для параллельной обработки на платформах, поддерживающих SIMD архитектуру SSSE3, AVX. См. Мультипакетная обработка .
pdwDataLen
[in/out] Если значение dwFlags нулевое, указатель на буфер, содержащий длину данных. Параметр pdwDataLen определяет число байтов шифртекста в буфере pbData. Через этот параметр функция возвращает указатель на число байтов открытого текста, помещённого в буфер pbData. Если установлен флаг CP_CRYPT_HASH_PACKET, размер буфера pbData в байтах. Если установлены флаги CP_CRYPT_HASH_PACKET и CP_CRYPT_DATA_IOVEC, передаётся число элементов массива CSP_iovec. Если установлены флаги CP_CRYPT_HASH_PACKET и CP_CHP_STARTMIX, по указателю pdwDataLen передаётся длина пакета включая блоб диверсификации ключей. Если установлены флаги CP_CRYPT_HASH_PACKET,CP_CRYPT_DATA_IOVEC и CP_CHP_STARTMIX, по указателю pdwDataLen передаётся число элементов вектора включая блоб диверсификации ключей (в этом варианте использования, блоб диверсификации должен передаваться отдельным первым элементом). Если установлены флаги CP_CRYPT_HASH_PACKET и CP_CHP_MULTIPACKET, указатель на число структур CSP_Multipacket_DEC.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_ALGID | Параметр AlgId определяет алгоритм, который не поддерживается криптопровайдером.
NTE_BAD_FLAGS | Величина dwFlags имеет некорректное значение, например, ненулевое значение при неустановленном флаге CP_CRYPT_HASH_PACKET.
NTE_BAD_DATA | Данные для расшифрования недействительны. В частности, в блочных режимах шифрования, если Final = FALSE, а длина шифртекста не кратна длине блока шифрования, возвращается данная ошибка. Эта ошибка также возвращается в блочных режимах шифрования, если используется дополнение (паддинг) PKCS#5, ISO 10126 или ANSI X.923, Final = TRUE, а дополнение блока не удовлетворяет условиям соответствующего дополнения. При шифровании пакета - ошибка формирования пакета.
NTE_BAD_LEN | Размер буфера недостаточен для полученного открытого текста.
NTE_PERM | Право расшифрования на данном ключе криптопровайдером не предоставлено.
NTE_BAD_KEY | Ключ недействителен.
NTE_BAD_HASH | Дескриптор хэша ошибочен. А также при расшифровании пакета с флагами CP_CHP_HASH_CHAIN, либо CP_CHP_HASH_PACKET рассчитанное значение хэш-функции не совпало со значением, полученным из пакета.
ERROR_FUNCTION_FAILED | нет лицензии, дающей право на выполнение функции расшифрования
NTE_FAIL | Нарушение целостности ключей в ОЗУ. см. Дополнительные параметры и определения .

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CPCEncrypt() ,CPCGenKey() ,CPDecrypt в MS CSP World Wide Web link ,CryptDecrypt в MS CryptoAPI 2.0 World Wide Web link


Функции хэширования и ЭП

Функции хэширования и ЭП предназначены для вычисления значения хэш функции и формирования/проверки ЭП данных.

Функции | Описание
CPCCreateHash | Функция CPCCreateHash() инициализирует дескриптор нового объекта функции хэширования потока данных.
CPCDestroyHash | Функция CPCDestroyHash() удаляет объект функции хэширования.
CPCDuplicateHash | Функция CPCDuplicateHash() создаёт точную копию объекта функции хэширования, включая все его переменные, определяющие внутреннее состояние объекта функции хэширования.
CPCGetHashParam | Функция CPCGetHashParam() возвращает параметры объекта функции хэширования и значение функции хэширования.
CPCHashData | Функция CPCHashData() передаёт данные указанному объекту функции хэширования.
CPCHashSessionKey | Функция CPCHashSessionKey() передаёт криптографический ключ указанному объекту функции хэширования. Это позволяет хэшировать ключи сессии без передачи ключа приложению.
CPCSetHashParam | Функция CPCSetHashParam() устанавливает параметры объекта хэширования.
CPCSignHash | Функция CPCSignHash() возвращает значение электронной цифровой подписи от значения функции хэширования.
CPCVerifySignature | Функция CPCVerifySignature() осуществляет проверку цифровой подписи.


CPCCreateHash

Функция CPCCreateHash() инициализирует дескриптор нового объекта функции хэширования потока данных.

DWORD CPCAPI CPCCreateHash(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  ALG_ID AlgId,
  HCRYPTKEY hKey,
  DWORD dwFlags,
  HCRYPTHASH * phHash
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
AlgId
[in] Идентификатор используемого алгоритма хэширования. В криптопровайдере определены следующие алгоритмы хэширования:
  • CALG_GR3411 - Алгоритм хэширования в соответствии с ГОСТ Р 34.11-94;
  • CALG_GR3411_2012_256 - Алгоритм хэширования в соответствии с ГОСТ Р 34.11-2012, длина выхода 256 бит.
  • CALG_GR3411_2012_512 - Алгоритм хэширования в соответствии с ГОСТ Р 34.11-2012, длина выхода 512 бит.
  • CALG_G28147_IMIT - Алгоритм имитозащиты в соответствии с ГОСТ 28147-89;
  • CALG_TLS1_MASTER_HASH - Объект, содержащий ключевую информацию для создания ключей CALG_TLS1_ENC_KEY и CALG_TLS1_MAC_KEY на основе алгоритма хэширования в соответствии с ГОСТ Р 34.11-94;
  • CALG_TLS1_MASTER_HASH_2012_256 - Объект, содержащий ключевую информацию для создания ключей CALG_TLS1_ENC_KEY и CALG_TLS1_MAC_KEY на основе алгоритма хэширования в соответствии с ГОСТ Р 34.11-2012;
  • CALG_PBKDF2_94_256 - Объект, содержащий ключевую информацию для выработки ключа из пароля на основе алгоритма хэширования в соответствии с ГОСТ Р 34.11-94, длина выхода 256 бит;
  • CALG_PBKDF2_2012_256 - Объект, содержащий ключевую информацию для выработки ключа из пароля на основе алгоритма хэширования в соответствии с ГОСТ Р 34.11-2012, длина выхода 256 бит;
  • CALG_PBKDF2_2012_512 - Объект, содержащий ключевую информацию для выработки ключа из пароля на основе алгоритма хэширования в соответствии с ГОСТ Р 34.11-2012, длина выхода 512 бит;
  • CALG_TLS1PRF - Алгоритм "производящей функции" (PRF), генерирующей блок данных произвольной длины на основе ключа, метки и бинарных данных, базирующийся на алгоритме хэширования в соответствии с ГОСТ Р 34.11-94.
  • CALG_TLS1PRF_2012_256 - Алгоритм "производящей функции" (PRF), генерирующей блок данных произвольной длины на основе ключа, метки и бинарных данных, базирующийся на алгоритме хэширования в соответствии с ГОСТ Р 34.11-2012.
  • CALG_GR3411_HMAC - Алгоритм ключевого хэширования на базе алгоритма ГОСТ Р 34.11-94 и сессионного ключа CALG_G28147.
  • CALG_GR3411_2012_256_HMAC - Алгоритм ключевого хэширования на базе алгоритма ГОСТ Р 34.11-2012 и сессионных ключей CALG_G28147/CALG_SYMMETRIC_512, длина выхода 256 бит.
  • CALG_GR3411_2012_512_HMAC - Алгоритм ключевого хэширования на базе алгоритма ГОСТ Р 34.11-2012 и сессионных ключей CALG_G28147/CALG_SYMMETRIC_512, длина выхода 512 бит.
  • CALG_EKEVERIFY_HASH - Алгоритм ключевого хэширования в протоколе взаимодействия с функциональным ключевым носителем. Ключ должен иметь тип CALG_PRO_AGREEDKEY_DH. Данные должны быть составлены в порядке, соответствующем полям структуры TOKEN_VERIFYDATA, за исключением поля Verify, и должны иметь длину sizeof(TOKEN_VERIFYDATA)- sizeof(DWORD). Данные должны подаваться на функцию хэширования одним блоком. Длина данных, возвращаемых через CPGetHashParam() – 4 байта.
  • CALG_MD5 - Алгоритм хэширования MD5 (RFC 1321).
  • CALG_SHA1 - Алгоритм хэширования SHA-1 (RFC 3174, FIPS PUB 180-1).
  • CALG_SHA_256 - Алгоритм хэширования SHA-256 (FIPS PUB 180-3).
  • CALG_SHA_384 - Алгоритм хэширования SHA-384 (FIPS PUB 180-3).
  • CALG_SHA_512 - Алгоритм хэширования SHA-512 (FIPS PUB 180-3).
  • CALG_UECMASTER_DIVERS - Объект, содержащий ключевую информацию ключа CALG_UECSYMMETRIC для диверсификации ключей карт с использованием CPCDeriveKey().
  • CALG_SHAREDKEY_HASH - Объект, содержащий ключевую информацию симметричного ключа для разложения в компоненты с использованием CPCDeriveKey().
  • CALG_FITTINGKEY_HASH - Объект, предназначен для сбора компонент в ключ CALG_UECSYMMETRIC с занесением в ключевой контейнер, если отсутствует AT_UECSYMMETRICKEY, либо в ключ CALG_G28147, CALG_UECSYMMETRIC_EPHEM, с использованием CPCHashSessionKey(), результирующий ключ производится функцией CPCDeriveKey().
  • CALG_GR3411_HMAC_FIXEDKEY - Алгоритм ключевого хэширования на базе алгоритма ГОСТ Р 34.11-94 с фиксированным сессионным ключом CALG_G28147. Ключ на вход не передается, а устанавливается после с помощью функции SetHashParam с параметром HP_HMAC_FIXEDKEY. Для использования в библиотеке IPsec.
  • CALG_GR3411_2012_256_HMAC_FIXEDKEY - Алгоритм ключевого хэширования на базе алгоритма ГОСТ Р 34.11-2012 с фиксированным сессионным ключом CALG_SYMMETRIC_512, длина выхода 256 бит. Ключ на вход не передается, а устанавливается после с помощью функции SetHashParam с параметром HP_HMAC_FIXEDKEY. Для использования в библиотеке IPsec.
  • CALG_GR3411_2012_512_HMAC_FIXEDKEY - Алгоритм ключевого хэширования на базе алгоритма ГОСТ Р 34.11-2012 с фиксированным сессионным ключом CALG_SYMMETRIC_512, длина выхода 512 бит. Ключ на вход не передается, а устанавливается после с помощью функции SetHashParam с параметром HP_HMAC_FIXEDKEY. Для использования в библиотеке IPsec.
  • CALG_GR3411_PRFKEYMAT - Алгоритм "производящей функции" (PRF) на базе алгоритма ГОСТ Р 34.11-94 и сессионного ключа CALG_G28147, генерирующей блок данных произвольной длины на основе бинарных данных (seed). Seed устанавливается через SetHashParam HP_PRFKEYMAT_SEED.
  • CALG_GR3411_2012_256_PRFKEYMAT - Алгоритм "производящей функции" (PRF) на базе алгоритма ГОСТ Р 34.11-2012 и сессионных ключей CALG_G28147/CALG_SYMMETRIC_512, генерирующей блок данных произвольной длины на основе бинарных данных (seed). Seed устанавливается через SetHashParam HP_PRFKEYMAT_SEED.
  • CALG_GR3411_2012_512_PRFKEYMAT - Алгоритм "производящей функции" (PRF) на базе алгоритма ГОСТ Р 34.11-2012 и сессионных ключей CALG_G28147/CALG_SYMMETRIC_512, генерирующей блок данных произвольной длины на основе бинарных данных (seed). Seed устанавливается через SetHashParam HP_PRFKEYMAT_SEED.
hKey
[in] Если используется алгоритм имитозащиты по ГОСТ 28147-89 (CALG_G28147_IMIT), в этом параметре передаётся ключ сессии для объекта функции хэширования.

Если используется алгоритм CALG_TLS1_MASTER_HASH или CALG_TLS1_MASTER_HASH_2012_256, в этом параметре передается master_secret (ключ типа CALG_TLS1_MASTER), на основе которого будет создана ключевая информация по следующей формуле:

      key_block = PRF(SecurityParameters.master_secret,
                         "key expansion",
                         SecurityParameters.server_random +
                         SecurityParameters.client_random);
Предварительно следует установить KP_CLIENT_RANDOM и KP_SERVER_RANDOM.

Если используется алгоритм CALG_TLS1PRF или CALG_TLS1PRF_2012_256, в этом параметре передается ключ типа CALG_TLS1_MASTER.

Для алгоритмов хэширования типа ГОСТ Р 34.11-94 и ГОСТ Р 34.11-2012 этот параметр должен быть установлен в ноль.
dwFlags
[in] Значения флагов.
phHash
[out] Адрес по которому функция копирует дескриптор нового объекта функции хэширования.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_ALGID | Параметр AlgId определяет алгоритм, который не поддерживается криптопровайдером.
NTE_BAD_FLAGS | Величина dwFlags имеет ненулевое значение.
NTE_BAD_KEY | Дескриптор исходного ключа ошибочен либо ключ не действителен.
NTE_NO_MEMORY | Криптопровайдер во время операции исчерпал память.
NTE_FAIL | Ошибка при считывании данных из системного реестра. см. Дополнительные параметры и определения .

Примечания

Использование алгоритмов CALG_MD5, CALG_SHA_256, CALG_SHA_384, CALG_SHA_512 не входит в функционал СКЗИ КриптоПро CSP 4.0, относящийся к действию сертификата ФСБ.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CPCDestroyHash() ,CPCHashData() ,CPCreateHash в MS CSP World Wide Web link ,CryptCreateHash в MS CryptoAPI 2.0 World Wide Web link


CPCDestroyHash

Функция CPCDestroyHash() удаляет объект функции хэширования.

DWORD CPCAPI CPCDestroyHash(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  HCRYPTHASH hHash
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
hHash
[in] Дескриптор удаляемого объекта функции хэширования.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
NTE_BAD_TYPE | Тип алгоритма hHash ошибочен.
NTE_BAD_HASH | Дескриптор хэша ошибочен.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CPCCreateHash() ,CPDestroyHash в MS CSP World Wide Web link ,CryptDestroyHash в MS CryptoAPI 2.0 World Wide Web link


CPCDuplicateHash

Функция CPCDuplicateHash() создаёт точную копию объекта функции хэширования, включая все его переменные, определяющие внутреннее состояние объекта функции хэширования.

DWORD CPCAPI CPCDuplicateHash(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  HCRYPTHASH hHash,
  DWORD * pdwReserved,
  DWORD dwFlags,
  HCRYPTHASH * phHash
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
hHash
[in] Дескриптор объекта функции хэширования.
pdwReserved
[in] Параметр зарезервирован для будущего использования и должен быть NULL.
dwFlags
[in] Параметр зарезервирован для будущего использования и должен быть нулевым.
phHash
[out] Адрес, по которому функция копирует дескриптор нового объекта функции хэширования.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_HASH | Дескриптор исходного хэша ошибочен.
NTE_NO_MEMORY | Криптопровайдер во время операции исчерпал память.
NTE_BAD_FLAGS | Параметр dwFlags имеет ненулевое значение.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CPCDestroyHash() ,CPDuplicateHash в MS CSP World Wide Web link ,CryptDuplicateHash в MS CryptoAPI 2.0 World Wide Web link


CPCGetHashParam

Функция CPCGetHashParam() возвращает параметры объекта функции хэширования и значение функции хэширования.

DWORD CPCAPI CPCGetHashParam(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  HCRYPTHASH hHash,
  DWORD dwParam,
  BYTE * pbData,
  DWORD * pdwDataLen,
  DWORD dwFlags
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
hHash
[in] Дескриптор объекта функции хэширования, параметры которого определяются.
dwParam
[in] Параметр, принимающий следующие возможные значения:
Значение dwParam | Содержимое буфера pbData
HP_ALGID | Алгоритм функции хэширования. Идентификатор алгоритма (ALG_ID), соответствующий данному объекту функции хэширования. Возвращается через буфер pbData. В pdwDataLen будет возвращена величина 4.
HP_HASHSIZE | Размер значения функции хэширования. Величина DWORD, определяющая число байтов в значении функции хэширования, будет возвращена через буфер pbData. В pdwDataLen будет возвращена величина 4.
HP_HASHVAL Значение функции хэширования в little-endian порядке байт в соответствии с типом GostR3411-94-Digest CPCMS [RFC 4490]. Вычисленное значение функции хэширования будет возвращено через буфер pbData. Длина значения функции хэширования будет возвращена в pdwDataLen.
Во время вызова функции объект хэша "закрывается".
Для ГОСТ Р 34.11-94 и ГОСТ Р 34.11-2012 (и HMAC-ов на их основе) проводится дополнение до размера блока (если требуется), исполняются шаговые функции для последнего блока (если требуется), для длины и для контрольной суммы.
Для ГОСТ 28147-89 в режиме имитовставки проводится дополнение до размера блока (если требуется), и исполняется шаговая функции для последнего блока (если требуется).
Расчёт хэш-функции может быть продолжен с помощью:
  • последующего вызова *SetHashParam(HP_OPEN, TRUE) для CSP 3.6 и выше;
  • предварительного вызова *DuplicateHash() - стандартный для Microsoft способ;
HP_R2_SIGN Возвращает значение R2 в алгоритме распределённой подписи, вырабатываемой с использованием функционального ключевого носителя. Через параметр pbData возвращается значение данных - точка эллиптической кривой в аффинных координатах (X,Y), длина данных – 64 бита.
Закрывает объект функции хэшироваия. Специфика протокола ООО "КРИПТО-ПРО" взаимодействия с функциональным ключевым носителем.
HP_R_SIGN Возвращает значение R в алгоритме распределённой подписи, вырабатываемой с использованием функционального ключевого носителя. Через параметр pbData возвращается значение данных - точка эллиптической кривой в аффинных координатах (X,Y), длина данных – 64 бита.
Специфика протокола ООО "КРИПТО-ПРО" взаимодействия с функциональным ключевым носителем.
HP_SHAREDMODE | Возвращает значение числа от 2 до 5 компонент, на которые раскладывается ключ объектом CALG_SHAREDKEY_HASH, либо собирается ключ объектом CALG_FITTINGKEY_HASH.
HP_IKE_SPI_COOKIE | Возвращает 32-35 байты значения хэша (при нумерации 0..63) для объектов типа CALG_GR3411_2012_512 и CALG_GR3411_2012_512_HMAC.
*pbData
[out] Указатель на буфер данных параметра. Функция копирует соответствующие параметру данные в буфер. Формат этих данных зависит от значения dwParam. Если параметр - NULL, то данные не копируются. Требуемый размер буфера в байтах возвращается в pdwDataLen. Подробнее см. Возвращение данных неопределенной длины.
*pdwDataLen
[in/out] Указатель на буфер, содержащий длину данных параметра. При вызове функции указанный параметр содержит число байтов в буфере pbData. После её исполнения параметр будет установлен числом байтов данных параметра, скопированных в буфер pbData. Если буфер, соответствующий pbData, недостаточно большой, чтобы в него копировать запрошенные данные, будет возвращен код ошибки ERROR_MORE_DATA через функцию SetLastError(). В этом случае требуемый размер буфера возвращается в pdwDataLen. Если функция завершается с кодом ошибки, отличным от ERROR_MORE_DATA, в этом параметре возвращается ноль.
dwFlags
[in] Значения флагов. Параметр зарезервирован для будущего использования и должен быть нулевым.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_HASH | Дескриптор хэша ошибочен.
ERROR_MORE_DATA | Размер буфера pbData недостаточен для копирования затребованных данных.
NTE_BAD_FLAGS | Параметр dwFlags имеет ненулевое значение.
NTE_BAD_TYPE | Параметр dwParam передаёт неизвестное значение параметра.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CPCCreateHash() ,CPCGetKeyParam() ,CPCSetHashParam() ,CPGetHashParam в MS CSP World Wide Web link ,CryptGetHashParam в MS CryptoAPI 2.0 World Wide Web link


CPCHashData

Функция CPCHashData() передаёт данные указанному объекту функции хэширования.

DWORD CPCAPI CPCHashData(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  HCRYPTHASH hHash,
  CONST BYTE * pbData,
  DWORD dwDataLen,
  DWORD dwFlags
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
hHash
[in] Дескриптор объекта функции хэширования. Приложение получает этот дескриптор, используя функцию CPCCreateHash().
pbData
[in] Если значение dwFlags нулевое, указатель на буфер, содержащий данные для хэширования. Если установлен флаг CP_HASH_DATA_IOVEC указатель на массив структур CSP_iovec. См. Вектор ввода вывода .
dwDataLen
[in] Если значение dwFlags нулевое, число байтов хэшируемых данных. Если установлен флаг CP_HASH_DATA_IOVEC, число элементов массива CSP_iovec.
dwFlags
[in] Значения флагов. Параметр определяет способ обработки фрагмента данных в потоке. Нулевое значение соответствует хэшированию фрагмента данных потока, флаг CP_HASH_DATA_IOVEC соответствует обработке данных в форме вектора ввода/вывода. См. Вектор ввода вывода .

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_ALGID | Ключ сессии hKey определяет алгоритм, который данный криптопровайдер не поддерживает.
NTE_BAD_HASH | Дескриптор хэша ошибочен.
NTE_BAD_HASH_STATE | Была сделана попытка добавить данные к объекту функции хэширования, который уже отмечен как "закрытый".
NTE_BAD_KEY | Используется алгоритм хэширования (CALG_G28147_IMIT), но сессионный ключ удалён прежде, чем действие хэширования завершено.
NTE_BAD_FLAGS | Величина dwFlags имеет значение, отличное от нулевого либо от CP_HASH_DATA_IOVEC.
NTE_BAD_LEN | Величина dwDataLen при установленном флаге CP_HASH_DATA_IOVEC имеет значение, превосходящее CSP_UIO_MAXIOV.
NTE_FAIL | Нарушение целостности ключей в ОЗУ.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CPCCreateHash() ,CPCHashSessionKey() ,CPHashData в MS CSP World Wide Web link ,CryptHashData в MS CryptoAPI 2.0 World Wide Web link


CPCHashSessionKey

Функция CPCHashSessionKey() передаёт криптографический ключ указанному объекту функции хэширования. Это позволяет хэшировать ключи сессии без передачи ключа приложению.

DWORD CPCAPI CPCHashSessionKey(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  HCRYPTHASH hHash,
  HCRYPTKEY hKey,
  DWORD dwFlags
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
hHash
[in] Дескриптор объекта функции хэширования. Приложение получает этот дескриптор, используя функцию CPCCreateHash().
hKey
[in] Дескриптор хэшируемого ключа сессии. Хэш типа CALG_FITTINGKEY_HASH собирает ключи в единый ключ, создаваемый функцией CPCDeriveKey().
dwFlags
[in] Значение CRYPT_LITTLE_ENDIAN соответствует хэшированию ключа в порядке байт, определяемым ГОСТ 28147-89, нулевое значение соответствует хэшированию в обратном порядке байт ключа.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
NTE_BAD_HASH | Дескриптор хэша ошибочен.
NTE_BAD_ALGID | Параметр AlgId определяет алгоритм, который не поддерживается криптопровайдером.
NTE_BAD_HASH_STATE | Была сделана попытка добавить данные к объекту функции хэширования, который уже отмечен как "закрытый".
NTE_BAD_KEY | Тип хэшируемого ключа не соответствует ALG_TYPE_BLOCK.

Примечания

Функция CPCHashSessionKey() добавляет к объекту функции хэширования только значение сессионного ключа hKey. Приложение должно самостоятельно добавлять к этому объекту дополнительные величины, такие как стартовый вектор шифрования и т.п.

Использование функции с dwFlags равным 0 не рекомендуется - поведение не определено.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CPCCreateHash() ,CPCGenKey() ,CPCHashData() ,CPHashSessionKey в MS CSP World Wide Web link ,CryptHashSessionKey в MS CryptoAPI 2.0 World Wide Web link


CPCSetHashParam

Функция CPCSetHashParam() устанавливает параметры объекта хэширования.

DWORD CPCAPI CPCSetHashParam(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  HCRYPTHASH hHash,
  DWORD dwParam,
  BYTE * pbData,
  DWORD dwFlags
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
hHash
[in] Дескриптор объекта хэширования, параметры которого устанавливаются.
dwParam
[in] Параметр, принимающий следующие возможные значения:
Значение dwParam | Содержимое буфера pbData
HP_HASHVAL | Устанавливается для объекта функции хэширования типа CALG_GR3411, CALG_GR3411_2012_256 и CALG_GR3411_2012_512. Величина, 32 байта для объектов типа CALG_GR3411 и CALG_GR3411_2012_256, 64 байта для объектов типа CALG_GR3411_2012_512, в little-endian порядке байт в соответствии с типом GostR3411-94-Digest CPCMS [RFC 4490], должна быть установлена в буфер pbData.
HP_HASHSIZE | Устанавливается для объекта функции хэширования типа CALG_G28147_IMIT. В буфер pbData записывается величина DWORD, определяющая число байтов имитовставки в диапазоне от 1 до 4. По умолчанию длина имитовставки равна 4 байтам.
KP_HASHOID | Идентификатор функции хэширования. Строка, заканчивающаяся нулем. Не допускается задавать для объектов типа CALG_GR3411_HMAC / CALG_GR3411_HMAC34, CALG_GR3411_2012_256_HMAC / CALG_GR3411_2012_512_HMAC и CALG_GR3411_2012_256 / CALG_GR3411_2012_512.
HP_TLS1PRF_SEED | Составляющая аргумента функции GOSTR3411_PRF. Принимает различные значения в сообщениях клиента и сервера при реализации TLS Handshake Protocol. Задается в виде структуры CRYPT_DATA_BLOB.
HP_TLS1PRF_LABEL | Составляющая аргумента функции GOSTR3411_PRF. Принимает различные значения в сообщениях клиента и сервера при реализации TLS Handshake Protocol. Задается в виде структуры CRYPT_DATA_BLOB.
HP_PBKDF2_SALT | Задает синхропосылку размерности от 8 до 32 байт для объекта хэша типа CALG_PBKDF2_94_256, CALG_PBKDF2_2012_256 и CALG_PBKDF2_2012_512. Задается в виде структуры CRYPT_DATA_BLOB.
HP_PBKDF2_PASSWORD | Задает пароль для объекта хэша типа CALG_PBKDF2_94_256, CALG_PBKDF2_2012_256 и CALG_PBKDF2_2012_512. Задается в виде структуры CRYPT_DATA_BLOB.
HP_PBKDF2_COUNT | Устанавливается для объекта функции хэширования типа CALG_PBKDF2_94_256, CALG_PBKDF2_2012_256 и CALG_PBKDF2_2012_512. В буфер pbData записывается величина DWORD, определяющая число итераций алгоритма. По умолчанию количество итераций равно 2000, минимальное допустимое значение параметра 1000.
HP_OPEN | Если через параметр pbData передаётся величина FALSE типа DWORD, производит повторную инициализацию объекта хэша типа CALG_GR3411, CALG_GR3411_HMAC, CALG_GR3411_HMAC34, CALG_G28147_IMIT, CALG_GR3411_2012_256, CALG_GR3411_2012_512, CALG_GR3411_2012_256_HMAC, CALG_GR3411_2012_512_HMAC в случае, если он закрыт. Если в pbData передаётся величина TRUE типа DWORD, закрытый объект функции хэширования типа CALG_GR3411, CALG_GR3411_2012_256, CALG_GR3411_2012_512 или CALG_G28147_IMIT открывается для дальнейшего хэширования данных.
HP_KEYMIXSTART | Осуществляет диверсификацию ключа, ассоциированного с объектом хэширования, по алгоритму CALG_PRO_DIVERS. Через параметр pbData передаётся блоб диверсификации ключа в форме CRYPT_DATA_BLOB, см. CPCImportKey(). Допускается многократный вызов с различными параметрами диверсификации.
HP_KEYSPEC_SIGN | Задает ключевую пару из открытого контейнера, на которой будут производиться вычисления в алгоритме распределенной подписи. Через параметр pbData передаётся значение типа ALG_ID, которое может быть равным AT_KEYEXCHANGE или AT_SIGNATURE. Установка данного параметра обязательно должна предшествовать применению алгоритма распределенной подписи. Специфика протокола ООО "КРИПТО-ПРО" взаимодействия с функциональным ключевым носителем.
HP_R2_SIGN | Устанавливает значение R2 в алгоритме распределённой подписи, вырабатываемой с использованием функционального ключевого носителя. Через параметр pbData передаётся структура типа CRYPT_HASH_BLOB_EX, где в качестве данных выступает точка эллиптической кривой в аффинных координатах (X,Y). Закрывает объект функции хэшироваия. Специфика протокола ООО "КРИПТО-ПРО" взаимодействия с функциональным ключевым носителем.
HP_R_SIGN | Устанавливает значение R в алгоритме распределённой подписи, вырабатываемой с использованием функционального ключевого носителя. Через параметр pbData передаётся типа CRYPT_HASH_BLOB_EX, где в качестве данных выступает точка эллиптической кривой в аффинных координатах (X,Y). Специфика протокола ООО "КРИПТО-ПРО" взаимодействия с функциональным ключевым носителем.
HP_S2_SIGN | Устанавливает значение ЭП, выработанное на стороне функционального ключевого носителя. Через параметр pbData передаётся значение типа CRYPT_HASH_BLOB_EX, где в качестве данных выступает значение ЭП (R,S2). Специфика протокола ООО "КРИПТО-ПРО" взаимодействия с функциональным ключевым носителем.
HP_SHAREDMODE | Устанавливает значение числа от 2 до 5 компонент, на которые раскладывается ключ объектом CALG_SHAREDKEY_HASH, либо собирается ключ объектом CALG_FITTINGKEY_HASH.
HP_HMAC_FIXEDKEY | Устанавливает значение ключа для объекта хэша типа CALG_GR3411_HMAC_FIXEDKEY, CALG_GR3411_2012_256_HMAC_FIXEDKEY и CALG_GR3411_2012_512_HMAC_FIXEDKEY. Через параметр pbData передаётся ключ в форме CRYPT_DATA_BLOB. Если размер переданных в блобе данных меньше размера соответствующего ключа, то ключ дополняется нулями, иначе - в качестве ключа устанавливается результат хэширования переданных данных.
HP_PRFKEYMAT_SEED | Устанавливает значение seed для объекта хэша типа CALG_GR3411_PRFKEYMAT, CALG_GR3411_2012_256_PRFKEYMAT и CALG_GR3411_2012_512_PRFKEYMAT. Через параметр pbData передаётся seed в форме CRYPT_DATA_BLOB.
pbData
[in] Указатель на буфер данных параметра. При вызове функции буфер содержит данные, соответствующие значению параметра в dwParam. Формат данных зависит от типа параметра dwParam.
dwFlags
[in] Значения флагов. Параметр зарезервирован для будущего использования и должен быть нулевым.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_HASH | Дескриптор хэша ошибочен.
NTE_BAD_FLAGS | Параметр dwFlags имеет ненулевое значение.
NTE_BAD_TYPE | Параметр dwParam передаёт неизвестное значение параметра.
NTE_BAD_HASH_STATE | Была сделана попытка получить значение функции хэширования для "не закрытого" объекта функции хэширования.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CPCCreateHash() ,CPCGetHashParam() ,CPCSignHash() ,CPSetHashParam в MS CSP World Wide Web link ,CryptSetHashParam в MS CryptoAPI 2.0 World Wide Web link


CPCSignHash

Функция CPCSignHash() возвращает значение электронной цифровой подписи от значения функции хэширования.

DWORD CPCAPI CPCSignHash(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  HCRYPTHASH hHash,
  DWORD dwKeySpec,
  LPCWSTR sDescription,
  DWORD dwFlags,
  BYTE * pbSignature,
  DWORD * pdwSigLen
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
hHash
[in] Дескриптор объекта функции хэширования, который будет подписан.
Для хэш с алгоритмами CALG_MD5, CALG_SHA1, CALG_SHA_256, CALG_SHA_384, CALG_SHA_512 функция может отработать успешно, но значение подписи всегда будет неопределённым.
dwKeySpec
[in] Тип ключевой пары, использующейся при подписи значения функции хэширования. Могут быть использованы следующие значения:
Значение | Описание
AT_KEYEXCHANGE | Ключевая пара обмена
AT_SIGNATURE | Ключевая пара цифровой подписи
sDescription
[in] Описание подписываемых данных, добавляемых к объекту hash перед тем, как будет произведена подпись. При проверке подписи функцией CPCVerifySignature() необходимо использовать то же описание подписанных данных. Это гарантирует, что подписывающая сторона и проверяющая знают то, что подписывается или проверяется. Если описание не включается в подпись, этот параметр устанавливается в NULL.

Параметр сохранён для совместимости со спецификацией Microsoft Cryptographic Service Provider. С целью предотвращения уязвимости безопасности ЭП использовать этот параметр не рекомендуется. Он должен быть установлен в NULL.
dwFlags
[in] Значения флагов. Параметр зарезервирован для будущего использования и должен быть нулем.
pbSignature
[in] Указатель на буфер, через который возвращается значение подписи. Если через этот параметр передаётся NULL, то подпись не вычисляется. В этом случае требуемый размер буфера (в байтах) возвращается через параметр pdwSigLen.
pdwSigLen
[in/out] Указатель на буфер, содержащий длину данных подписи. При вызове функции указанный параметр должен содержать число байтов в буфере pbSignature. После её исполнения параметр будет установлен числом байтов данных, скопированных в буфер pbSignature. Если буфер, соответствующий pbSignature, недостаточно большой, чтобы в него копировать подпись, будет возвращён код ошибки ERROR_MORE_DATA через функцию SetLastError(). В этом случае требуемый размер буфера возвращается в pdwSigLen. Если эта функция завершается с кодом ошибки, отличным от ERROR_MORE_DATA, в этом параметре возвращается ноль. Подпись для ключей ГОСТ Р 34.10-2001 возвращается как описано CPPK (RFC 4491), но в обратном порядке байт. Например, подпись сертификата п. 4.2 будет возвращена:

 {
 0xE2, 0xDE, 0x33, 0x1C, 0xB5, 0xD5, 0x31, 0xB1, 0xDA, 0xF4, 0x20, 0x62, 0x17, 0x89, 0x89, 0x68,
 0x77, 0x55, 0x93, 0x36, 0xDD, 0xF3, 0x93, 0xB5, 0x71, 0xEC, 0x1B, 0x8D, 0x6E, 0x17, 0xDE, 0xC1,
 0xDD, 0x3F, 0x54, 0xBC, 0x4F, 0x45, 0x16, 0x31, 0xED, 0xDE, 0x2E, 0x44, 0x7C, 0x64, 0xAA, 0xC3,
 0xD2, 0x6D, 0x53, 0xFB, 0xE9, 0xD5, 0xA7, 0xEC, 0xA9, 0x27, 0xB7, 0x44, 0x09, 0xC9, 0x2F, 0x3C
 }

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_ALGID | Дескриптор hHash определяет алгоритм, который данный криптопровайдер не поддерживает.
NTE_BAD_FLAGS | dwFlags параметр отличен от нуля, либо параметр dwKeySpec содержит ошибочную величину.
NTE_BAD_HASH | Дескриптор хэша ошибочен.
NTE_NO_KEY | Закрытый ключ, указанный dwKeySpec, не существует.
NTE_NO_MEMORY | Криптопровайдер во время операции исчерпал память.
ERROR_MORE_DATA | pbSignature буфер мал для копирования затребованных данных.
NTE_FAIL | Нарушение целостности ключей в ОЗУ. см. Дополнительные параметры и определения .
SCARD_W_CANCELLED_BY_USER | Пользователь прервал операцию нажатием клавиши Cancel
SCARD_W_WRONG_CHV | Пользователь ввёл неправильный пароль или пароль, установленный функцией SetProvParam(), неправильный
SCARD_E_INVALID_CHV | Пользователь ввёл пароль с нарушением формата или пароль, установленный функцией SetProvParam(), имеет неправильный формат. Например, пароль имеет недопустимую длину или содержит недопустимые символы.
SCARD_W_CHV_BLOCKED | Ввод Pin-кода был заблокирован смарт-картой, т.к. исчерпалось количество попыток, разрешенное картой для ввода.
NTE_SILENT_CONTEXT | Операция не может быть выполнена без пользовательского интерфейса.
SCARD_W_REMOVED_CARD | Носитель контейнера был удален из считывателя
ERROR_FUNCTION_FAILED | нет лицензии, дающей право на выполнение функции подписи

Примечания

В режиме ядра ОС перед использованием этой функции необходимо вызвать CPCImportKey с ключевым блобом типа PRIVATEKEYBLOB, чтобы задать ключ, на котором будет осуществлена подпись.

Перед вызовом функции CPCSignHash() необходимо получить дескриптор объекта хэширования при помощи функции CPCCreateHash(). После этого используется функция CPCHashData() или CPCHashSessionKey() чтобы добавить данные или ключи сессии к объекту хэширования.

Функция CPCSignHash() выполняет следующие внутренние шаги:

  • объект функции хэширования "закрывается”; извлекается значение функции хэширования;
  • значение функции хэширования дополняется, как это требуется алгоритмом подписи;
  • вычисляется фактическое значение подписи.

    После того, как объект функции хэширования подписан, приложение не может добавлять к нему новые данные. Поэтому вызовы функций CPCHashData() или CPCHashSessionKey() приведут к ошибке. Однако, дополнительные вызовы функций CPCDeriveKey(), CPCGetHashParam(), CPCSignHash() и CPCVerifySignature() будут успешными. Эти функции будут работать с подписанным объектом функции хэширования. Приложение должно удалить объект функции хэширования при помощи функции CPCDestroyHash().

При использовании ключей алгоритма ГОСТ Р 34.10-2001 для формирования электронной подписи необходимо использовать алгоритм хэширования ГОСТ Р 34.11-94.

При использовании ключей алгоритма ГОСТ Р 34.10-2012 длины 256 бит для формирования электронной подписи необходимо использовать алгоритм хэширования ГОСТ Р 34.11-2012 (256 бит).

При использовании ключей алгоритма ГОСТ Р 34.10-2012 длины 512 бит для формирования электронной подписи необходимо использовать алгоритм хэширования ГОСТ Р 34.11-2012 (512 бит).

Использование алгоритмов CALG_MD5, CALG_SHA_256, CALG_SHA_384, CALG_SHA_512 не входит в функционал СКЗИ КриптоПро CSP 4.0, относящийся к действию сертификата ФСБ.

Рекомендуется, по возможности, непосредственно после формирования подписи осуществить ее проверку.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CPCCreateHash() ,CPCDestroyHash() ,CPCHashData() ,CPCHashSessionKey() ,CPCVerifySignature() ,CPSignHash в MS CSP World Wide Web link ,CryptSignHash в MS CryptoAPI 2.0 World Wide Web link


CPCVerifySignature

Функция CPCVerifySignature() осуществляет проверку цифровой подписи.

DWORD CPCAPI CPCVerifySignature(
  HCRYPTMODULE hCSP,
  HCRYPTPROV hProv,
  HCRYPTHASH hHash,
  CONST BYTE * pbSignature,
  DWORD dwSigLen,
  HCRYPTKEY hPubKey,
  LPCWSTR sDescription,
  DWORD dwFlags
);

Аргументы

hCSP
[in] Указатель на таблицу функций криптопровайдера. Получается при помощи функции CPCCreateProvider()
hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPCAcquireContext().
hHash
[in] Дескриптор объекта функции хэширования, подпись которого проверяется.
Для хэш с алгоритмами CALG_MD5, CALG_SHA1, CALG_SHA_256, CALG_SHA_384, CALG_SHA_512 функция имеет неопределённое поведение.
pbSignature
[in] Указатель на буфер, содержащий значение проверяемой подписи.
dwSigLen
[in] Длина (в байтах) значения подписи.
hPubKey
[in] Дескриптор открытого ключа проверяемой подписи. Недопустимо использоание одного ключа в многопоточной обработке. Для организации многопоточной обработки необходимо размножать ключ с использованием функции CPCDuplicateKey().
sDescription
[in] Описание подписанных данных идентичное описанию, использованному при создании подписи. Это должна быть точно та же самая последовательность, которая использовалась в функции CPCSignHash() при создании подписи. Если эта последовательность не соответствует использованной в функции CPCSignHash(), проверка подписи сообщит, что подпись не верна.
dwFlags
[in] Значения флагов. Параметр зарезервирован для будущего использования и должен быть нулевым.

Возвращаемые значения

При успешном завершении функция возвращает 0 (S_OK), в противном случае возвращается соответствующий код ошибки (см. таблицу).
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_ALGID | Дескриптор hHash определяет алгоритм, который этот криптопровайдер не поддерживает.
NTE_BAD_FLAGS | dwFlags параметр отличен от нуля.
NTE_BAD_KEY | hPubKey параметр содержит дескриптор на недопустимый открытый ключ.
NTE_BAD_HASH | Дескриптор хэша ошибочен.
NTE_BAD_SIGNATURE | Проверка подписи не прошла (могли измениться подписанные данные, или значение подписи, открытый ключ был определён ошибочно параметром hPubKey). Эта ошибка может быть возвращена также, если алгоритмы хэширования или подписи не соответствуют тем, с помощью которых вычислялась подпись.
NTE_NO_MEMORY | Криптопровайдер во время операции исчерпал память.
NTE_FAIL | Нарушение целостности ключей в ОЗУ.
RPE_CORRUPT_KEYPAIR_INFO | Нарушение целостности ключей.

Примечания

Функция CPCVerifySignature выполняет следующие внутренние шаги:

  • если параметр описания sDescription поддержан, он добавляется к объекту функции хэширования;
  • объект функции хэширования "закрывается" и значение функции хэширования извлекается;
  • значение функции хэширования дополняется, как это требуется алгоритмом подписи;
  • осуществляется проверка подписи c использованием открытого ключа hPubKey;
  • если подпись, переданная через буфер pbSignature, и вычисленное значение подписи не совпадают, возвращается код ошибки NTE_BAD_SIGNATURE.

    После того, как объект функции хэширования подписан, приложение не может добавлять к нему новые данные. Поэтому вызовы функций CPCHashData() или CPCHashSessionKey() приведут к ошибке. Однако, дополнительные вызовы функций CPCDeriveKey(), CPCGetHashParam(), CPCSignHash() и CPCVerifySignature() будут успешными. Эти функции будут работать с подписанным объектом функции хэширования. Приложение должно удалить объект функции хэширования при помощи функции CPCDestroyHash().

При использовании ключей алгоритма ГОСТ Р 34.10-2001 для проверки электронной подписи необходимо использовать алгоритм хэширования ГОСТ Р 34.11-94.

При использовании ключей алгоритма ГОСТ Р 34.10-2012 длины 256 бит для проверки электронной подписи необходимо использовать алгоритм хэширования ГОСТ Р 34.11-2012 (256 бит).

При использовании ключей алгоритма ГОСТ Р 34.10-2012 длины 512 бит для проверки электронной подписи необходимо использовать алгоритм хэширования ГОСТ Р 34.11-2012 (512 бит).

Использование алгоритмов CALG_MD5, CALG_SHA_256, CALG_SHA_384, CALG_SHA_512 не входит в функционал СКЗИ КриптоПро CSP 4.0, относящийся к действию сертификата ФСБ.

Требования:

Ядро FreeBSD: 7/8/9 или выше
Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше
Ядро Solaris: 10/11 или выше.
Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

См. также

CPCCreateHash() ,CPCHashData() ,CPCSignHash() ,CPVerifySignature в MS CSP World Wide Web link ,CryptVerifySignature в MS CryptoAPI 2.0 World Wide Web link


Особенности использования интерфейса уровня ядра в Windows

Общее описание

Интерфейс "КриптоПро CSP 4.0" уровня ядра в Windows реализован в драйвере cpdrvlib.sys. Этот драйвер запускается при инициализации операционной системы (в последовательности SERVICE_SYSTEM_START).

Если функции вашего драйвера существенно зависят от интерфейса уровня ядра "КриптоПро CSP 4.0", вы можете задать вашему драйверу зависимость на загрузку от cpdrvlib.sys, чтобы обеспечить его запуск строго после запуска cpdrvlib.sys.

Для использования интерфейса уровня ядра "КриптоПро CSP 4.0" драйвер-клиент должен получить адреса точек входа. Это делается с помощью отправки запросов ввода/вывода к устройству драйвера с именем CPDRVLIB_NT_DEVICE_NAME. Необходимые коды IOCTL и имя устройства определены в файле cpdrvlib.h. Запрос ввода/вывода должен производиться с кодом IRP_MJ_INTERNAL_DEVICE_CONTROL. Точки входа, предоставляемые cpdrvlib.sys, и соответствующие им коды IOCTL представлены в таблице:

Точка входа | Код IOCTL для получения адреса
CPCCreateProvider | IOCTL_GETCPCCREATEPROVIDER
CPCGetDefaultConfig | IOCTL_GETCPCGETDEFAULTCONFIG
CPCInitMemoryLF | IOCTL_GETCPCINITMEMORYLF

Примечания

Адреса остальных функций интерфейса получаются путём вызова CPCCreateProvider.

Для отправки запроса ввода/вывода к устройству драйвера cpdrvlib.sys, драйвер-клиент должен получить указатель на это устройство, например, с помощью функции IoGetDeviceObjectPointer. Вызов этой функции увеличит счётчик ссылок на устройство драйвера cpdrvlib.sys, что предотвратит его отгрузку до закрытия соответствующего файла путём вызова ObDereferenceObject в драйвере-клиенте. Закройте этот файл только после того, как закончите работу с функциями интерфейса уровня ядра, т.к. в противном случае отгрузка драйвера cpdrvlib.sys приведёт к тому, что управление будет передано на неинициализированную страницу памяти или в неизвестный код.

В конфигурации по умолчанию используется максимальные возможности процессора (AVX/SSE3) (они используются при IRQL <= DISPATCH_LEVEL, для изменения функционирования или отключения используйте поля FuncStruct.UsedMask/UsesFunctions и др. в CPC_CONFIG_).

В конфигурации по умолчанию используется R/W блокировки ExAcquireResourceSharedLite/ExAcquireResourceSharedLite совместно с CriticalRegion, поэтому без флага CRYPT_NOSERIALIZE CSP может быть вызван только при IRQL <= APC_LEVEL. Для корректной работы память под объекты из MP_PRIME, MP_PRIME_M, MP_SEC_M должна выделяться в NonPagedPool. Если требуется работа на более высоких IRQL - задайте собственные callback-и синхронизации lockFuncs в CPC_CONFIG_, или, если работа c CSP осуществляется под внешними блокировками, отключите их путём присвоения нулевых указателей.

Пример получения адресов точек входа

Сначала необходимо получить указатель на устройство драйвера cpdrvlib.sys.

 #include <ntddk.h>
 #include <cpdrvlib.h>
 #include <wincspc.h>

 UNICODE_STRING deviceNameUnicodeString;
 PDEVICE_OBJECT CPDevice;
 PFILE_OBJECT CPFile;

 RtlInitUnicodeString(&deviceNameUnicodeString, CPDRVLIB_NT_DEVICE_NAME);
 IoGetDeviceObjectPointer(&deviceNameUnicodeString, FILE_READ_DATA, &CPFile,
        &CPDevice);

Далее приводится пример получения адреса функции CPCCreateProvider.

 KEVENT Event;
 IO_STATUS_BLOCK IoStatusBlock;
 PIRP pIrp;
 CPCCreateProvider_t *CreateProvider;

 KeInitializeEvent(&Event, NotificationEvent, FALSE);
 pIrp = IoBuildDeviceIoControlRequest(IOCTL_GETCPCCREATEPROVIDER,
        CPDevice, NULL, 0, &CreateProvider, sizeof(CreateProvider), TRUE,
        &Event, &IoStatusBlock);
 IoCallDriver(CPDevice, pIrp);


Особенности использования интерфейса уровня ядра в OC Linux

Общее описание

Интерфейс "КриптоПро CSP 4.0" уровня ядра в Linux реализован в модуле ядра drvcsp.ko. Этот модуль запускается из инициализационных командных файлов операционной системы (см. /etc/modules.conf).

Для Linux способ связывания - ссылка на символы. Точки входа, предоставляемые drvcsp.ko представлены в таблице:

Точка входа
CPCCreateProvider
CPCGetDefaultConfig
CPCInitMemoryLF

Примечания

Адреса остальных функций интерфейса получаются путём вызова CPCCreateProvider.

Для работы с данными функциями достаточно объявить их прототипы:

 #include "wincspc.h"
 #include "wincspc_int.h"

Примечания

В ОС Linux модули ядра не обладают бинарной совместимостью и, соответственно, привязаны к конкретной версии ядра ОС. Поэтому модуль ядра поставляется в виде пакета .src.rpm. Такой тип пакета позволяет собрать модуль для нужной версии ядра. Для его установки следует при помощи rpmbuild собрать из .src.rpm пакета обычный .rpm пакет, а затем установить его. Подробнее этот процесс описан в разделе "Установка дистрибутива ПО СКЗИ" руководства администратора безопасности Linux.

Так как наличие средств отладки и разработки на системах, в которых эксплуатируется СКЗИ "КриптоПро CSP 4.0", недопустимо, администратор (разработчик ПКЗИ) должен собрать пакет типа rpm на специальном выделенном рабочем месте и обеспечивать его доверенную установку в целевую систему.

Для Intel Pentium (i386/i586/i686/amd) ядро Linux обычно поддерживает размер стека равный 2*4Кб. "КриптоПро CSP 4.0" уровня ядра требуется максимум 3Кб (обычно менее 2Кб).

Для Intel EM64T (x86_64/x64/amd64) ядро Linux обычно поддерживает размер стека равный 2*8Кб. "КриптоПро CSP 4.0" уровня ядра требуется максимум 5Кб (обычно менее 4Кб).

Лицензия

В функции CPCCreateProvider проверяется лицензия, которая должна быть передана в структуре CPC_CONFIG_. При отсутствии или искажении лицензии функция вернёт ошибку.

Обычно следует использовать функцию CPCGetDefaultConfig, которая возвращает конфигурацию по умолчанию, в частности, лицензию "КриптоПро CSP 4.0" установленную стандартным образом (примечание: после установки новой лицензии следует перезагрузить модуль drvcsp.ko).

Пример получения адресов точек входа

Данный пример демонстрирует способ вызов функции CPCCreateProvider.

Включаем определение типа wchar_t и др., согласно ISO/IEC 9899.

 #include <stddef.h>
Подключаем требуемые файлы Linux DDK и Крипто-Про DDK.

 #include "drtcsp_io.h"
 #include "reader/tchar.h"
 #include "reader/support.h"
 #include "wincspc.h"
 #include "wincspc_int.h"
 #include "lfmm.h"
 #include "lfmm_int.h"
Подготавливаем данные для вызова CPCCreateProvider:

 CPC_CONFIG CSPConfig;
 CPCGetDefaultConfig(&CSPConfig, NULL);
 CSPConfig.logConfig.name=_TEXT(MODNAME);
Заполняем структуры менеджера памяти. В данном случае используем безблокировочный менеджер памяти, т.е. инициализируем его структуры данных и вызываем CPCInitMemoryLF

 CPCInitMemoryLF(&CSPConfig.pArena,&lfmmConfig);
Инициализируем CPCCreateProvider

 HCRYPTMODULE hCSP;
 CPCCreateProvider(&hCSP,&Config);

Управление памятью и синхронизация уровня ядра Linux

При использовании на уровне ядра ОС ПКЗИ должно предоставить функции управления памятью и синхронизации соответствующие фактическому уровню исполнения.

Т.к. в ядре ОС Linux, в общем случае, ожидающие блокировки невозможны, рекомендуется использовать безблокировочный менеджер памяти, не заполнять lockFuncs и открывать контексты с флагом CRYPT_NOSERIALIZE. В этом случае ПКЗИ должно учитывать, что в следующих случаях результат будет не определён:

  • "Параллельное" удаление контекста и осуществление операций над объектами этого контекста;
  • "Параллельное" проведение операций изменяющих состояние одного и того же объекта (шифрование, вычисление хэш функции);
Операции в разных контекстах и/или над разными объектами можно выполнять "параллельно", в том числе при обработке аппаратных или программных прерываний.

В ядре Linux не требуется настраивать примитивы синхронизации interlockedFuncs, т.к. процессоры Intel Pentium/EM64T имеют соответствующие встроенные команды.

Регрессионное тестирование ПКЗИ уровня ядра ОС

Для разработки и отладки ПКЗИ уровня ядра ОС на уровне приложений предназначена библиотека libcpcdrv_emul.a. Сборка, отладка, а так же измерение фактического максимального размера стека осуществляется обычным образом. Измерения фактически использованного размера памяти в безблокировочном менеджере осуществляется функцией CPC_StatMemory.


Интерфейс криптопровайдера "КриптоПро CSP 4.0"

Функции, структуры, параметры внешнего интерфейса криптопровайдера "КриптоПро CSP 4.0".

  • Дополнительные параметры и определения
  • Инициализация и параметры криптопровайдера
  • Функции генерации и работы с ключами
  • Функции шифрования/расшифрования данных
  • Функции хэширования и ЭП
  • Структуры данных
  • Примеры использования функций "КриптоПро CSP 4.0"


Дополнительные параметры и определения

Данный раздел содержит определения идентификаторов и параметров, используемых в криптопровайдере "КриптоПро CSP".

  • Идентификаторы алгоритмов криптопровайдера
  • Режимы шифрования
  • Параметры криптопровайдера
  • Параметры дополнительных ключевых блобов
  • Дополнительные параметры объекта хэширования
  • Дополнительные параметры ключей
  • Групповые идентификаторы криптографических параметров алгоритмов
  • Идентификаторы криптографических параметров алгоритмов
  • Имя контейнера
  • Возвращение данных неопределенной длины


Идентификаторы алгоритмов криптопровайдера

Идентификатор | Описание идентификатора
CALG_GR3411 | Идентификатор алгоритма хэширования по ГОСТ Р 34.11-94.
CALG_GR3411_2012_256 | Идентификатор алгоритма хэширования в соответствии с ГОСТ Р 34.11-2012, длина выхода 256 бит.
CALG_GR3411_2012_512 | Идентификатор алгоритма хэширования в соответствии с ГОСТ Р 34.11-2012, длина выхода 512 бит.
CALG_G28147_MAC | Идентификатор алгоритма имитозащиты по ГОСТ 28147-89.
CALG_G28147_IMIT | То же самое, что и CALG_G28147_MAC (устаревшая версия).
CALG_GR3410 | Идентификатор алгоритма ЭЦП по ГОСТ Р 34.10-94.
CALG_GR3410EL | Идентификатор алгоритма ЭЦП по ГОСТ Р 34.10-2001.
CALG_GR3410_12_256 | Идентификатор алгоритма ЭЦП по ГОСТ Р 34.10-2012 (256 бит).
CALG_GR3410_12_512 | Идентификатор алгоритма ЭЦП по ГОСТ Р 34.10-2012 (512 бит).
CALG_GR3411_HMAC | Идентификатор алгоритма ключевого хэширования на базе алгоритма ГОСТ Р 34.11-94 и сессионного ключа CALG_G28147.
CALG_GR3411_2012_256_HMAC | Идентификатор алгоритма ключевого хэширования на базе алгоритма ГОСТ Р 34.11-2012 и сессионного ключа CALG_G28147, длина выхода 256 бит.
CALG_GR3411_2012_512_HMAC | Идентификатор алгоритма ключевого хэширования на базе алгоритма ГОСТ Р 34.11-2012 и сессионного ключа CALG_G28147, длина выхода 512 бит.
CALG_G28147 | Идентификатор алгоритма шифрования по ГОСТ 28147-89.
CALG_SYMMETRIC_512 | Идентификатор алгоритма выработки ключа парной связи по Диффи-Хеллману с длиной выхода 512 бит.
CALG_DH_EX_SF | Идентификатор алгоритма обмена ключей по Диффи-Хеллману на базе закрытого ключа пользователя.
CALG_DH_EX_EPHEM | Идентификатор CALG_DH_EX алгоритма обмена ключей по Диффи-Хеллману на базе закрытого ключа эфемерной пары. Открытый ключ получается по ГОСТ Р 34.10 94.
CALG_DH_EX | Идентификатор CALG_DH_EX алгоритма обмена ключей по Диффи-Хеллману на базе закрытого ключа пользователя. Открытый ключ получается по ГОСТ Р 34.10 94.
CALG_DH_EL_SF | Идентификатор алгоритма обмена ключей по Диффи-Хеллману на базе закрытого ключа пользователя. Открытый ключ получается по ГОСТ Р 34.10 2001.
CALG_DH_EL_EPHEM | Идентификатор алгоритма обмена ключей по Диффи-Хеллману на базе закрытого ключа эфемерной пары. Открытый ключ получается по ГОСТ Р 34.10 2001.
CALG_DH_GR3410_12_256_SF | Идентификатор алгоритма обмена ключей по Диффи-Хеллману на базе закрытого ключа пользователя. Открытый ключ получается по ГОСТ Р 34.10 2012 (256 бит).
CALG_DH_GR3410_12_256_EPHEM | Идентификатор алгоритма обмена ключей по Диффи-Хеллману на базе закрытого ключа эфемерной пары. Открытый ключ получается по ГОСТ Р 34.10 2012 (256 бит).
CALG_DH_GR3410_12_512_SF | Идентификатор алгоритма обмена ключей по Диффи-Хеллману на базе закрытого ключа пользователя. Открытый ключ получается по ГОСТ Р 34.10 2012 (512 бит).
CALG_DH_GR3410_12_512_EPHEM | Идентификатор алгоритма обмена ключей по Диффи-Хеллману на базе закрытого ключа эфемерной пары. Открытый ключ получается по ГОСТ Р 34.10 2012 (512 бит).
CALG_PRO_AGREEDKEY_DH | Идентификатор алгоритма выработки ключа парной связи по Диффи-Хеллману.
CALG_PRO_EXPORT | Идентификатор алгоритма защищённого экспорта ключа.
CALG_PRO12_EXPORT | Идентификатор алгоритма защищённого экспорта ключа по рекомендациям ТК26 (обязателен для использования с ключами ГОСТ Р 34.10-2012).
CALG_SIMPLE_EXPORT | Идентификатор алгоритма простого экспорта ключа.
CALG_TLS1PRF | Идентификатор алгоритма "производящей функции" (PRF) протокола TLS 1.0 на основе алгоритма хэширования в соответствии с ГОСТ Р 34.11-94.
СALG_TLS1PRF_2012_256 | Идентификатор алгоритма "производящей функции" (PRF) протокола TLS 1.0 на основе алгоритма хэширования в соответствии с ГОСТ Р 34.11-2012.
CALG_TLS1_MASTER_HASH | Идентификатор алгоритма выработки объекта MASTER_HASH протокола TLS 1.0 на основе алгоритма хэширования в соответствии с ГОСТ Р 34.11-94.
CALG_TLS1_MASTER_HASH_2012_256 | Идентификатор алгоритма выработки объекта MASTER_HASH протокола TLS 1.0 на основе алгоритма хэширования в соответствии с ГОСТ Р 34.11-2012.
CALG_TLS1_MAC_KEY | Идентификатор алгоритма выработки ключа имитозащиты протокола TLS 1.0.
CALG_TLS1_ENC_KEY | Идентификатор алгоритма выработки ключа шифрования протокола TLS 1.0.
CALG_PBKDF2_94_256 | Идентификатор алгоритма выработки ключа из пароля на основе алгоритма хэширования в соответвии с ГОСТ Р 34.11-94, длина выхода 256 бит.
CALG_PBKDF2_2012_256 | Идентификатор алгоритма выработки ключа из пароля на основе алгоритма хэширования в соответвии с ГОСТ Р 34.11-2012, длина выхода 256 бит.
CALG_PBKDF2_2012_512 | Идентификатор алгоритма выработки ключа из пароля на основе алгоритма хэширования в соответвии с ГОСТ Р 34.11-2012, длина выхода 512 бит.
CALG_PRO_DIVERS | Идентификатор алгоритма КриптоПро диверсификации ключа по RFC 4357.
CALG_PRO12_DIVERS | Идентификатор алгоритма КриптоПро диверсификации ключа по рекомендациям ТК26.
CALG_RIC_DIVERS | Идентификатор алгоритма РИК диверсификации ключа.


Режимы шифрования

Параметр | Значение параметра
CRYPT_PROMIX_MODE | Задание режимов шифрования/расшифрования по ГОСТ 28147-89 с преобразованием ключа через каждые 1 КВ обрабатываемой информации
CRYPT_SIMPLEMIX_MODE | Задание режимов шифрования/расшифрования по ГОСТ 28147-89 без преобразования ключа в процессе обработки информации


Параметры криптопровайдера

Параметр | Значение параметра
PP_ENUMOIDS_EX | Получает перечень идентификаторов объектов, используемых в криптопровайдере
PP_HASHOID | Получает и/или устанавливает заданный в контейнере OID узла замены функции хэширования ГОСТ Р 34.11-94 для наследования криптографическими объектами
PP_CIPHEROID | Получает и/или устанавливает заданный в контейнере OID узла замены алгоритма шифрования ГОСТ 28147-89 для наследования криптографическими объектами
PP_SIGNATUREOID | Получает и/или устанавливает заданный в контейнере OID параметров цифровой подписи - в зависимости от типа провайдера
PP_DHOID | Получает и/или устанавливает заданный в контейнере OID параметров алгоритма Диффи-Хеллмана в зависимости от типа провайдера
PP_CHECKPUBLIC | Флаг контроля открытого ключа. Если флаг установлен, осуществляется проверка алгебраических свойств открытого ключа
PP_RANDOM | Получает и/или устанавливает блоб типа SIMPLEBLOB для инициализации ДСЧ в драйвере шифрования
PP_DRVCONTAINER | Получает указатель (handle) контейнера в драйвере
PP_MUTEX_ARG | Инициализирует синхронизацию потоков криптопровайдера в драйверном исполнении
PP_ENUM_HASHOID | Получает перечень идентификаторов криптографических объектов, связанных с функцией хэширования
PP_ENUM_CIPHEROID | Получает перечень идентификаторов криптографических объектов, связанных с функцией шифрования
PP_ENUM_SIGNATUREOID | Получает перечень идентификаторов криптографических объектов, связанных с функцией цифровой подписи, - PP_ENUM_SIGNATUREOID_256_2001, PP_ENUM_SIGNATUREOID_256_2012 или PP_ENUM_SIGNATUREOID_512 в зависимости от типа провайдера
PP_ENUM_DHOID | Получает перечень идентификаторов криптографических объектов, связанных с алгоритмом Диффи-Хеллмана, в зависимости от типа провайдера


Параметры дополнительных ключевых блобов

Параметр | Значение параметра
DIVERSKEYBLOB | Тип ключевого блоба для диверсификации ключей с помощью функции CPImportKey в режиме CALG_PRO_EXPORT


Дополнительные параметры объекта хэширования

Параметр | Значение параметра
HP_HASHSTARTVECT | Стартовый вектор функции хэширования, устанавливаемый приложением
HP_OID | Задает узел замены функции хэширования


Дополнительные параметры ключей

Параметр | Значение параметра
KP_IV | Начальный вектор инициализации алгоритма шифрования ГОСТ 28147-89
KP_MIXMODE | Определяет использование преобразования ключа после обработки 1КВ информации в режимах шифрования/расшифрования и вычисления имитовставки алгоритма ГОСТ 28147-89
KP_OID | Задает узел замены функции хэширования
KP_HASHOID | Идентификатор узла замены функции хэширования ГОСТ Р 34.11-94
KP_CIPHEROID | Идентификатор узла замены алгоритма шифрования ГОСТ 28147-89
KP_SIGNATUREOID | Идентификатор параметров цифровой подписи
KP_DHOID | Идентификатор параметров алгоритма Диффи-Хеллмана


Групповые идентификаторы криптографических параметров алгоритмов

Параметр | Индекс | Значение параметра
szOID_CP_GOST_28147 | "1.2.643.2.2.21" | Алгоритм шифрования ГОСТ 28147-89
szOID_CP_GOST_R3411 | "1.2.643.2.2.9" | Функция хэширования ГОСТ Р 34.11-94
szOID_CP_GOST_R3411_12_256 | "1.2.643.7.1.1.2.2" | Функция хэширования ГОСТ Р 34.11-2012, длина выхода 256 бит
szOID_CP_GOST_R3411_12_512 | "1.2.643.7.1.1.2.3" | Функция хэширования ГОСТ Р 34.11-2012, длина выхода 512 бит
szOID_CP_GOST_R3410 | "1.2.643.2.2.20" | Алгоритм ГОСТ Р 34.10-94, используемый при экспорте/импорте ключей
szOID_CP_GOST_R3410EL | "1.2.643.2.2.19" | Алгоритм ГОСТ Р 34.10-2001, используемый при экспорте/импорте ключей
szOID_CP_GOST_R3410_12_256 | "1.2.643.7.1.1.1.1" | Алгоритм ГОСТ Р 34.10-2012 для ключей длины 256 бит, используемый при экспорте/импорте ключей
szOID_CP_GOST_R3410_12_512 | "1.2.643.7.1.1.1.2" | Алгоритм ГОСТ Р 34.10-2012 для ключей длины 512 бит, используемый при экспорте/импорте ключей
szOID_CP_DH_EX | "1.2.643.2.2.99" | Алгоритм Диффи-Хеллмана на базе потенциальной функции
szOID_CP_DH_EL | "1.2.643.2.2.98" | Алгоритм Диффи-Хеллмана на базе эллиптической кривой
szOID_CP_DH_12_256 | "1.2.643.7.1.1.6.1" | Алгоритм Диффи-Хеллмана на базе эллиптической кривой для ключей длины 256 бит
szOID_CP_DH_12_512 | "1.2.643.7.1.1.6.2" | Алгоритм Диффи-Хеллмана на базе эллиптической кривой для ключей длины 512 бит
szOID_CP_GOST_R3411_R3410 | "1.2.643.2.2.4" | Алгоритм цифровой подписи ГОСТ Р 34.10-94
szOID_CP_GOST_R3411_R3410EL | "1.2.643.2.2.3" | Алгоритм цифровой подписи ГОСТ Р 34.10-2001
szOID_CP_GOST_R3411_12_256_R3410 | "1.2.643.7.1.1.3.2" | Алгоритм цифровой подписи ГОСТ Р 34.10-2012 для ключей длины 256 бит
szOID_CP_GOST_R3411_12_512_R3410 | "1.2.643.7.1.1.3.3" | Алгоритм цифровой подписи ГОСТ Р 34.10-2012 для ключей длины 512 бит
szOID_KP_TLS_PROXY | "1.2.643.2.2.34.1" | Аудит TLS-трафика
szOID_KP_RA_CLIENT_AUTH | "1.2.643.2.2.34.2" | Идентификация пользователя на центре регистрации
szOID_KP_WEB_CONTENT_SIGNING | "1.2.643.2.2.34.3" | Подпись содержимого сервера Интернет


Идентификаторы криптографических параметров алгоритмов

Параметр | Индекс | Значение параметра
szOID_GostR3411_94_TestParamSet | "1.2.643.2.2.30.0" | Тестовый узел замены
szOID_GostR3411_94_CryptoProParamSet | "1.2.643.2.2.30.1" | Узел замены функции хэширования по умолчанию, вариант "Верба-О"
szOID_GostR3411_94_CryptoPro_B_ParamSet | "1.2.643.2.2.30.2" | Узел замены функции хэширования, вариант 1
szOID_GostR3411_94_CryptoPro_C_ParamSet | "1.2.643.2.2.30.3" | Узел замены функции хэширования, вариант 2
szOID_GostR3411_94_CryptoPro_D_ParamSet | "1.2.643.2.2.30.4" | Узел замены функции хэширования, вариант 3
szOID_Gost28147_89_TestParamSet | "1.2.643.2.2.31.0" | Тестовый узел замены алгоритма шифрования
szOID_Gost28147_89_CryptoPro_A_ParamSet | "1.2.643.2.2.31.1" | Узел замены алгоритма шифрования по умолчанию, вариант "Верба-О"
szOID_Gost28147_89_CryptoPro_B_ParamSet | "1.2.643.2.2.31.2" | Узел замены алгоритма шифрования, вариант 1
szOID_Gost28147_89_CryptoPro_C_ParamSet | "1.2.643.2.2.31.3" | Узел замены алгоритма шифрования, вариант 2
szOID_Gost28147_89_CryptoPro_D_ParamSet | "1.2.643.2.2.31.4" | Узел замены алгоритма шифрования, вариант 3
szOID_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet | "1.2.643.2.2.31.5" | Узел замены, вариант карты КриптоРИК
szOID_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet | "1.2.643.2.2.31.6" | Узел замены, используемый при шифровании с хэшированием
szOID_Gost28147_89_TC26_A_ParamSet | "1.2.643.2.2.31.12" | Узел замены алгоритма шифрования, вариант ТК26 2
szOID_Gost28147_89_TC26_B_ParamSet | "1.2.643.2.2.31.13" | Узел замены алгоритма шифрования, вариант ТК26 1
szOID_Gost28147_89_TC26_C_ParamSet | "1.2.643.2.2.31.14" | Узел замены алгоритма шифрования, вариант ТК26 3
szOID_Gost28147_89_TC26_D_ParamSet | "1.2.643.2.2.31.15" | Узел замены алгоритма шифрования, вариант ТК26 4
szOID_Gost28147_89_TC26_E_ParamSet | "1.2.643.2.2.31.16" | Узел замены алгоритма шифрования, вариант ТК26 5
szOID_Gost28147_89_TC26_F_ParamSet | "1.2.643.2.2.31.17" | Узел замены алгоритма шифрования, вариант ТК26 6
szOID_Gost28147_89_TC26_Z_ParamSet | "1.2.643.7.1.2.5.1.1" | Узел замены алгоритма шифрования, вариант ТК26 Z
szOID_GostR3410_94_CryptoPro_A_ParamSet | "1.2.643.2.2.32.2" | Параметры P, Q, A цифровой подписи ГОСТ Р 34.10-94, вариант "Верба-О". Могут использоваться также в алгоритме Диффи-Хеллмана
szOID_GostR3410_94_CryptoPro_B_ParamSet | "1.2.643.2.2.32.3" | Параметры P, Q, A цифровой подписи ГОСТ Р 34.10-94, вариант 1. Могут использоваться также в алгоритме Диффи-Хеллмана
szOID_GostR3410_94_CryptoPro_C_ParamSet | "1.2.643.2.2.32.4" | Параметры P, Q, A цифровой подписи ГОСТ Р 34.10-94, вариант 2. Могут использоваться также в алгоритме Диффи-Хеллмана
szOID_GostR3410_94_CryptoPro_D_ParamSet | "1.2.643.2.2.32.5" | Параметры P, Q, A цифровой подписи ГОСТ Р 34.10-94, вариант 3. Могут использоваться также в алгоритме Диффи-Хеллмана
szOID_GostR3410_94_CryptoPro_XchA_ParamSet | "1.2.643.2.2.33.1" | Параметры P, Q, A алгоритма Диффи-Хеллмана на базе экспоненциальной функции, вариант 1
szOID_GostR3410_94_CryptoPro_XchB_ParamSet | "1.2.643.2.2.33.2" | Параметры P, Q, A алгоритма Диффи-Хеллмана на базе экспоненциальной функции, вариант 2
szOID_GostR3410_94_CryptoPro_XchC_ParamSet | "1.2.643.2.2.33.3" | Параметры P, Q, A алгоритма Диффи-Хеллмана на базе экспоненциальной функции, вариант 3
szOID_GostR3410_2001_TestParamSet | "1.2.643.2.2.35.0" | Тестовые параметры a, b, p, q, (x,y) алгоритма ГОСТ Р 34.10-2001
szOID_GostR3410_2001_CryptoPro_A_ParamSet | "1.2.643.2.2.35.1" | Параметры a, b, p, q, (x,y) цифровой подписи и алгоритма Диффи-Хеллмана на базе алгоритма ГОСТ Р 34.10-2001, вариант криптопровайдера
szOID_GostR3410_2001_CryptoPro_B_ParamSet | "1.2.643.2.2.35.2" | Параметры a, b, p, q, (x,y) цифровой подписи и алгоритма Диффи-Хеллмана на базе алгоритма ГОСТ Р 34.10-2001, вариант карты КриптоРИК
szOID_GostR3410_2001_CryptoPro_C_ParamSet | "1.2.643.2.2.35.3" | Параметры a, b, p, q, (x,y) цифровой подписи и алгоритма Диффи-Хеллмана на базе алгоритма ГОСТ Р 34.10-2001, вариант 1
szOID_GostR3410_2001_CryptoPro_XchA_ParamSet | "1.2.643.2.2.36.0" | Параметры a, b, p, q, (x,y) алгоритма Диффи-Хеллмана на базе алгоритма ГОСТ Р 34.10-2001, вариант криптопровайдера. Используются те же параметры, что и с идентификатором szOID_GostR3410_2001_CryptoPro_A_ParamSet
szOID_GostR3410_2001_CryptoPro_XchB_ParamSet | "1.2.643.2.2.36.1" | Параметры a, b, p, q, (x,y) цифровой подписи и алгоритма Диффи-Хеллмана на базе алгоритма ГОСТ Р 34.10-2001, вариант 1
szOID_tc26_gost_3410_12_256_paramSetA | "1.2.643.7.1.2.1.1.1" | Параметры a, b, p, q, (x,y) цифровой подписи и алгоритма Диффи-Хеллмана на базе алгоритма ГОСТ Р 34.10-2012 256 бит, набор A
szOID_tc26_gost_3410_12_512_paramSetA | "1.2.643.7.1.2.1.2.1" | Параметры a, b, p, q, (x,y) цифровой подписи и алгоритма Диффи-Хеллмана на базе алгоритма ГОСТ Р 34.10-2012 512 бит по умолчанию
szOID_tc26_gost_3410_12_512_paramSetB | "1.2.643.7.1.2.1.2.2" | Параметры a, b, p, q, (x,y) цифровой подписи и алгоритма Диффи-Хеллмана на базе алгоритма ГОСТ Р 34.10-2012 512 бит, набор B
szOID_tc26_gost_3410_12_512_paramSetC | "1.2.643.7.1.2.1.2.3" | Параметры a, b, p, q, (x,y) цифровой подписи и алгоритма Диффи-Хеллмана на базе алгоритма ГОСТ Р 34.10-2012 512 бит, набор C


Имя контейнера

Имя контейнера является строкой, заканчивающейся нулем, идентифицирующей носитель ключевой информации.

Возможные значения имени контейнера:

Значение | Описание
NULL | Контейнер по умолчанию. Если конфигурация "КриптоПро CSP" настроена на хранение ключей на диске, то именем контейнера по умолчанию является имя пользователя ОС, вызвавшего CSP.
CONTAINER | Имя контейнера.
MEDIA\UNIQUE | Контейнер по умолчанию на носителе (MEDIA\UNIQUE).
MEDIA\UNIQUE\FOLDER | Контейнер на заданном носителе (MEDIA\UNIQUE). Если носитель не поддерживает уникальных имен, то уникальное имя носителя отсутствует, но символ \ опускать в этом случае нельзя. Если носитель поддерживает длинные имена (например, реестр), то имя контейнера в этом случае совпадает FOLDER.
MEDIA\UNIQUE\FOLDER\CRC | Контейнер на заданном носителе (MEDIA\UNIQUE) с именем CRC16 которого в нижнем регистре в кодировке UTF8 совпадает с CRC. Если носитель не поддерживает уникальных имен, то уникальное имя носителя отсутствует, но символ \ опускать в этом случае нельзя.
\\.\READER\MEDIA\UNIQUE | Контейнер по умолчанию на носителе (MEDIA\UNIQUE), с заданным именем считывателя.
\\.\READER\MEDIA\UNIQUE\FOLDER | Контейнер на заданном носителе (MEDIA\UNIQUE), с заданным именем считывателя. Если носитель не поддерживает уникальных имен, то уникальное имя носителя отсутствует, но символ \ опускать в этом случае нельзя. Если носитель поддерживает длинные имена (например, реестр), то имя контейнера в этом случае совпадает с FOLDER.
\\.\READER\MEDIA\UNIQUE\FOLDER\CRC | Контейнер на заданном носителе (MEDIA\UNIQUE), с заданным именем считывателя и CRC16 имени контейнера в нижнем регистре в кодировке UTF8 совпадает с CRC Если носитель не поддерживает уникальных имен, то уникальное имя носителя отсутствует, но символ \ опускать в этом случае нельзя. Если носитель поддерживает длинные имена (например, реестр), то имя контейнера в этом случае совпадает с FOLDER.
\\.\READER\CONTAINER | Имя контейнера на заданном считывателе.
\\.\READER | Контейнер по умолчанию на заданном считывателе.

Во всех перечисленных выше формах (кроме NULL), оконечный символ \ не влияет на смысл контейнера.

Пользователь задаёт имя контейнера, возможно с заданием имени считывателя, в аргументах функции CPAcquireContext .

Функция CPGetProvParam возвращает:

  • имя контейнера (CONTAINER) как параметр PP_CONTAINER
  • и возвращает уникальное имя (MEDIA\UNIQUE\FOLDER\CRC) контейнера как параметр PP_UNIQUE_CONTAINER (Значение UNIQUE отсутствует для считывателей, не поддерживающих уникальность имен. Значение CRC отсутствует для носителей, поддерживающих длинные имена, т.е. для которых имя FOLDER ВСЕГДА совпадает с именем NAME).

Поддерживаемые считыватели

На данный момент поддерживаются следующие считыватели (READER):

Имя | Описание
FAT12_[DRIVE] | дисковод, где [DRIVE] имя дисковода, например, для дисковода A: имя FAT12_A
DS9097E_[COM], DS9097U_[COM], DS1410E_[LPT] | считыватель Touch-Memory, где [COM] ([LPT]) имя COM (LPT) порта, например, для считывателя Touch-Memory DS9097E, присоединенного ко второму COM порту, имя будет DS9097E_COM1
ACCORD | считыватель Touch-Memory через ACCORD
SABLE | считыватель Touch-Memory через Соболь
REGISTRY | считыватель ключей из реестра.
HDIMAGE | считыватель ключей с диска.
[PCSC считыватель] | считыватель смарт-карт через интерфейс PCSC, где [PCSC считыватель] имя считывателя так как он зарегистрирован, например для первого зарегистрированного считывателя GCR410 имя будет "GEMPLUS GCR410P 0"

Поддерживаемые носители

Поддерживаются следующие типы носителей (MEDIA):

Имя | Описание
FAT12 | дискета (или любой другой отчуждаемый носитель, поддерживающий файловую систему, понимаемую ОС)
DS | Touch-Memory
REGISTRY | реестр. Поддерживает длинные имена.
HDIMAGE | жесткий диск.
SCARD | смарт-карта, или любое другое устройство с интерфейсом смарт-карты, например, eToken.

Вид уникального номера

Вид уникального номера (UNIQUE) носителя в зависимости от его типа носителя:

Тип носителя | Вид уникального номера | Описание
Дискета | [SERIAL]_[VOLUME] | [SERIAL] серийный номер дискеты, 8 16-ричных цифр (задается при форматировании), [VOLUME] - метка тома 11 символов (задается при форматировании или, если нет метки, то при генерации первого контейнера). Если метка тома, по каким-то причинам отсутствует, то уникальное имя будет представлено в виде [SERIAL].
Touch-Memory | [тип]_[номер] | [тип] - тип Touch-memory на текущий момент поддерживаются 1993, 1994, 1995, 1996. [номер] - 6 16-ричных цифр уникального номера таблетки.
смарт-карта MPCOS 3DES | MPCOS-EMV_[номер] | [номер] - 16 16-ричных цифр уникального номера карты
смарт-карта и электронный ключ РИК | RIC_[номер] | [номер] 8 16-ричных цифр уникального номера карты
электронный ключ eToken HS | eToken_HS_[номер] | [номер] - 16 16-ричных цифр уникального номера электронного ключа
HDIMAGE | не поддерживается | не поддерживается
реестр | не поддерживается | не поддерживается

Вид имени папки (FOLDER) носителя в зависимости от типа носителя:

Тип носителя | Вид имени папки | Описание
Дискета, HDIMAGE | [имя].[NNN] | [имя] - 8 первых символов имени контейнера; Для символов от 'a' до 'z', от 'A' до 'Z', от '0' до '9' и символа '-' символы остаются без изменений, для остальных символов происходит замена на символ с ASCII кодом вычисляемым по формуле c%('z'-'a'+1)+'a', где c исходный символ имени контейнера. [NNN] - порядковый номер контейнера на этом носителе внутри множества совпадающих имен [имя].
Touch-Memory | [N] | [N] - 16-ричных порядковый номер контейнера на носителе
смарт-карта и электронные ключи | не поддерживается | не поддерживается
реестр | [имя] | [имя] - имя контейнера

Список поддерживаемых считывателей и типов носителей может быть изменен.

См. также

CPAcquireContext() ,CPGetProvParam() ,CPSetProvParam() ,CPAcquireContext в MS CSP World Wide Web link ,CPGetProvParam в MS CSP World Wide Web link ,CPSetProvParam в MS CSP World Wide Web link ,CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link ,CryptGetProvParam в MS CryptoAPI 2.0 World Wide Web link ,CryptSetProvParam в MS CryptoAPI 2.0 World Wide Web link


Возвращение данных неопределенной длины

Возвращение данных неопределенной длины

Многие функции криптопровайдера и CryptoAPI возвращают неопределенное количество данных по адресу, предоставленному через параметр функции. Во всех таких случаях операция производится в следующем порядке. Параметр, который содержит указатель на возвращаемые данные, записываетcя с префиксом "pb" или "pv" с последующим именем параметра. Другой параметр функции имеет префикс "pcb" с последующим именем параметра. Данный параметр определяет длину в байтах данных, которые будут возвращены в адреса, описанные переменными с префиксами "pb" или "pv". Следующий пример показывает спецификацию функции такого типа:

 BOOL WINAPI SomeFunction(
 PCCRL_CONTEXT pCrlContext,  // in
 DWORD dwPropId,             // in
 BYTE *pbData,               // out
 DWORD *pcbData              // in/out
 );

В данном примере параметр pbData содержит указатель на адрес, в который будут возвращены данные, а параметр pcbData определяет размет в байтах возвращаемых данных.

Примечание 1. Префикс параметров, содержащих возвращаемые данные, может иногда отличаться от "pcb", например "p" или "pv". Соответствующий параметр, определяющий длину данных тоже может иметь другой префикс, например для "pwsz" он может быть "pcch", где "pcch" определяет длину символов в кодировке Unicode или ASCII возвращаемых данных.

Если размер области памяти специфицированной параметром pbData недостаточен для возвращаемых данных, функция вернет код ошибки ERROR_MORE_DATA , который можно определить, используя функцию GetLastError, а в переменной pcbData установит требуемое количество байт памяти, необходимое для возвращаемых данных.

Если значение NULL указывается в качестве значения параметра pbData и переменная pcbData не NULL, ошибка не будет возвращена и функция возвратит размер требуемой памяти в байтах в переменной, определенной указателем pcbData. Это дает возможность приложению определить размер и зарезервировать требуемое количество памяти.

Примечание 2. Когда значение NULL указывается в качестве значения параметра pbData для определения размера возвращаемых данных, второй вызов функции может не использовать полностью область памяти. После второго вызова функции действительный размер данных возвращается по адресу переменной в pcbData. Используйте это значение для обработки данных.

Примечание 3. Использование двухпроходной схемы (NULL указывается в качестве значения параметра pbData) может приводить к снижению производительности для некоторых функций. К таким функциям в первую очередь относятся функции создания сообщений, относящийся к классам Low Level Message Functions и Simplified Message Functions, так как для определения размера сообщения производится его полное формирование, включая генерацию сеансовых ключей. Для приложений, в которых критерий производительности является определяющим, можно рекомендовать заранее резервировать буфер для выходных данных определенной длины и обрабатывать код возврата функции.

Последующие примеры показывают реализация обеих схем.

Процедура с учетом производительности

Данная процедура заранее резервирует буфер для возвращаемых данных . Если размер буфера на первом вызове достаточен для успешного завершения функции, получается выигрыш в производительности.

Следующий пример показывает способ переопределения размера буфера для получения выигрыша в производительности:

 //--------------------------------------------------------------------
 // Функция SomeFunction (из предыдущего примера) вызывается приложением
 // в цикле. Размер буфера для выходных данных устанавливается
 // значением 50 байт.

 //--------------------------------------------------------------------
 // Определение переменных функции SomeFunction.

 PCCRL_CONTEXT pCrlContext; // Инициализируется в другом месте.
 DWORD dwPropId;            // Инициализируется в другом месте.

 //--------------------------------------------------------------------
 // Изначально под буфер выделяется 50 байт. Затем этот буфер используется
 // при вызове функции SomeFunction, которая в большинстве случаев
 // осуществляет обработку и вывод некоторых желаемых данных.
 // Даже если для выходных данных требуется больше 50 байт, изначально
 // выделяется именно 50 байт. В этом случае первый вызов функции
 // будет неудачным, но возвращенное им значение cbData будет использоваться
 // для выделения большей памяти под буфер. Таким образом второй вызов
 // функции SomeFunction будет использовать буфер большей длины.

 //--------------------------------------------------------------------
 //   Считается, что переменные pCrlContext и dwPropId были определены
 //   и проинициализированы в другом месте.

 DWORD dwTries = 0; // количество вызовов функции
 BOOL fMore=TRUE;   // флаг, определяющий, следует ли осуществлять вызов
                      // функции
 DWORD cbData = 50;
 BYTE  *pbData;

 //--------------------------------------------------------------------
 //  Начало обработки. Этот цикл выполняется не более двух раз.

 while (fMore)
 {
 if (pbData = (BYTE *)malloc(cbData))
 {
      printf("Memory has been allocated.\n");
 }
 else
 {
      HandleError("Memory allocation error.");
 }
 //--------------------------------------------------------------------
 //  Память выделена. Вызов функции.

    if (SomeFunction(pCrlContext, dwPropId, pbData, &cbData))
        // Вызов функции был успешным. Выход из цикла.
    {
             printf("The function succeeded. Exit the loop.\n");
             fMore=FALSE;
    }
    else
    {
          // Вызов функции был неудачным. Освобождение выделенной памяти.
           free(pbData);  // Освобождение буфера в случае неудачного исхода.

          // Если ошибка отличается от того, что под буфер выделено
          // недостаточное количество памяти, то цикл успешно не
          // завершается. Обработка ошибки.

          if(GetLastError() != ERROR_MORE_DATA )
          {
               HandleError("General function failure.");
          }
          // Если ошибка заключается в том, что под буфер выделено
          // недостаточное количество памяти, то осуществляется вторая,
            // но не третья попытка.
          if( ++dwtries > 1 )
           {
               HandleError("Function call failed twice ");
           }
 }  // Конец цикла

 //--------------------------------------------------------------------
 //  Если цикл завершился, то вызов функции был успешным либо во время
 //  первой, либо во время второй итерации цикла. В обоих случаях в процессе
 //  выполнения значение cbData заменяется фактическим размером
 //  возвращаемых данных. Для обработки байт в буфере, на который указывает
 //  pbData, следует пользоваться этим размером.

 //--------------------------------------------------------------------
 //  В данном месте осуществляется обработка pbData.

 //--------------------------------------------------------------------
 //  Очистка после обработки.

 free(pbData); // Освобождение буфера данных
               // после того, как данные были обработаны.

Увеличение производительности может быть получено также за счет использования alloca для отведения памяти в стеке вместо использования malloc для отведения памяти в куче (heap). Из за того, что буфер находится в стеке, нет необходимости вызова free при завершении работы с буфером. При использовании alloc, данные буфера должны быть использованы локально, так как по завершению функции, буфер автоматически освобождается очисткой стека. Вместе с этим, вызов alloc уменьшает размер стека, что может провести к его переполнению.

Процедура с предварительным определением длины буфера

Следующий пример показывает способ определения требуемой длины буфера для возвращаемых данных:

 #include <stdio.h>;
 #include <windows.h>;
 #include <wincrypt.h>;
 #define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

 void HandleError(char *s);

 void main()
 {
 //--------------------------------------------------------------------
 // Определение переменных функции SomeFunction.

 PCCRL_CONTEXT pCrlContext; // Инициализируется в другом месте.
 DWORD dwPropId;            // Инициализируется в другом месте.
 DWORD cbData;
 BYTE  *pbData;

 //--------------------------------------------------------------------
 // Вызов функции SomeFunction для определения необходимого размера
 // буфера pbData. Это значение устанавливается в cbData.

 if(SomeFunction(
      pCrlContext,
      dwPropId,
      NULL,
      &cbData))
 {
        printf("The function succeeded.\n");
 }
 else
 {
 // Вызов функции завершился неудачей. Обработка ошибки.
        HandleError("Function call failed.");
 }

 //--------------------------------------------------------------------
 // Вызов функции был успешным. На данный момент cbData содержит
 // необходимый размер буфера в байтах.

 //--------------------------------------------------------------------
 // Выделение памяти в соответствии с размером сообщения.

 if(pbData = (BYTE*)malloc(cbData))
 {
    printf("Memory has been allocated.\n");
 }
 else
 {
    // Приложение потерпело неудачу. Вывод сообщения об ошибке и
    // выход из программы.
    HandleError("Malloc operation failed. ");
 }

 //--------------------------------------------------------------------
 // Память под буфер была выделена. Вызов функции SomeFunction
 // для заполнения буфера данными.

 if(SomeFunction(
       pCrlContext,
       dwPropId,
       pbData,
       &cbData))
 {
        printf("The function succeeded.\n");
 }
 else
 {
    // Повторный вызов функции завершился неудачей. Обработка ошибки.
    HandleError("The second call to the function failed.");
 }
 //*******************************************************************
 // Функия выполнилась успешно. На данный момент данные находятся в
 // буфере, на который указывает pbData. Необходимо помнить, что
 // в процессе выполнения значение cbData заменяется фактическим размером
 // возвращаемых данных. Для обработки байт в буфере, на который указывает
 // pbData, следует пользоваться этим размером.

 } // Конец main

 //--------------------------------------------------------------------
 // В этом примере используется функция HandleError для обработки
 // кода ошибок, вывода сообщения и выхода из программы. В приложениях
 // рекомендуется заменить данную функцию другой, которая позволит
 // произвести более подробную диагностику кода ошибки

 void HandleError(char *s)
 {
     fprintf(stderr,"An error occurred in running the program.\n");
     fprintf(stderr,"%s\n",s);
     fprintf(stderr,"Error number %x.\n",GetLastError());
     fprintf(stderr,"Program terminating.\n");
     exit(1);
 }


Инициализация и параметры криптопровайдера

Перечисленные функции предназначены для установления сессии прикладного ПО с криптопровайдером и получения (установки) параметров сессии.

Функции | Описание
CPAcquireContext | Функция CPAcquireContext() используется для создания дескриптора криптопровайдера с именем ключевого контейнера, определённым параметром pszContainer.
CPReleaseContext | Функция CPReleaseContext() используется для удаления дескриптора криптопровайдера, созданного CPAcquireContext().
CPGetProvParam | Функция CPGetProvParam() получает параметры криптопровайдера.
CPSetProvParam | Функция CPSetProvParam() устанавливает параметры криптопровайдера.


CPAcquireContext

Функция CPAcquireContext() используется для создания дескриптора криптопровайдера с именем ключевого контейнера, определённым параметром pszContainer.

BOOL WINAPI CPAcquireContext(
  HCRYPTPROV * phProv,
  CHAR * pszContainer,
  DWORD dwFlags,
  PVTABLEPROVSTRUC pVTable
);

Аргументы

phProv
[out] Адрес, по которому функция копирует дескриптор криптопровайдера.
pszContainer
[in] Имя ключевого контейнера. Это указатель на строку, длиной не больше, чем MAX_PATH знаков, включая признак конца строки. Если данный параметр - NULL, то криптопровайдер будет использовать в качестве имени контейнера имя пользователя, вошедшего в систему. Пользователь может получить имя используемого контейнера функцией CPGetProvParam(). Подробнее см. Дополнительные параметры и определения .
dwFlags
[in] Параметр имеет нулевое или одно из следующих значений:
Значение dwFlags | Описание
CRYPT_VERIFYCONTEXT | Приложение не имеет доступа к закрытым ключам ключевого контейнера. Флаг используется в приложениях, в которых требуется только проверка цифровой подписи. Операции, обычно необходимые в этом случае, – получение дескрипторов открытых ключей, хэширование и проверка подписи. При вызове функции CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link с этим флагом криптопровайдер не требует от пользователя ввода ключевой информации. Параметр pszContainer игнорируется, но рекомендуется устанавливать его значение в NULL.
CRYPT_NEWKEYSET | Если флаг установлен, то будет создан новый ключевой контейнер с именем, соответствующим pszContainer. Если pszContainer - NULL, то в качестве имени контейнера используется имя пользователя, вошедшего в систему.
CRYPT_MACHINE_KEYSET | Флаг может использоваться при вызове функции CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link c CRYPT_NEW_KEYSET или флагом CRYPT_DELETE_KEYSET. В этом случае ключи будут сохранены в ключе HKEY_LOCAL_MACHINE системного реестра. Флаг предназначен для использования криптопровайдера в составе приложений, не имеющих доступа к пользовательскому разделу реестра (сервис, драйвер и т.д.).
CRYPT_DELETEKEYSET | Ключевой контейнер, соответствующий pszContainer, удаляется. Если pszContainer - NULL, то удаляется ключевой контейнер, заданный по умолчанию (см. Дополнительные параметры и определения ). Все ключевые пары в ключевом контейнере также уничтожаются. Когда флаг CRYPT_DELETEKEYSET установлен, значение, возвращённое в phProv, не определено и повторный вызов функции CPReleaseContext() с тем же дескриптором phProv также не определён.
CRYPT_SILENT Флаг, запрещающий криптопровайдеру "КриптоПро CSP 4.0" использовать какой-либо пользовательский интерфейс (UI) при выполнении операций с данным контекстом. Можно задать этот флаг глобально для всех операций:
на 32-х битной Windows выполнить в коммандной строке с правами администратора:
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Crypto Pro\Cryptography\CurrentVersion\Parameters" /v force_silent /t REG_DWORD /d 1 /f
на 64-х битной Windows выполнить в коммандной строке с правами администратора:
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Crypto Pro\Cryptography\CurrentVersion\Parameters" /v force_silent /t REG_DWORD /d 1 /f
для остальных ОС выполнить в консоли с правами администратора из папки, содержащей утилиту cpconfig:
./cpconfig -ini '' -add long force_silent 1
Если дальнейшие вызовы функций криптопровайдера требуют отображения графического интерфейса, то криптопровайдер возвратит ошибку NTE_SILENT_CONTEXT.
CRYPT_NOSERIALIZE | Флаг, запрещающий криптопровайдеру "КриптоПро CSP 4.0" использовать ждущие блокировки при операциях создания/удаления объектов в данном контексте. При этом ответственность за недопущение параллельного вызова таких функций берёт на себя приложение. Параллельные обращения к таким функциям над одним и тем же контекстом возвращают ошибку.
CRYPT_TOKEN_SHARED | Флаг контекста взаимодействия с ключевым носителем в режиме разделения секрета, флаг предназначен для взаимодействия с функциональными ключевыми носителями по протоколам, разработанным ООО "КРИПТО-ПРО".
CRYPT_PROMT_INSERT_MEDIA | Используется совместно с CRYPT_NEWKEYSET. Если флаг установлен, то при создании контейнера будет показан диалог выбора считывателя, даже если считыватель один.
pVTable
[in] Указатель на структуру _VTABLEPROVSTRUC , которая содержит список callback функций, представляемых операционной системой для использования криптопровайдером.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возврата | Описание
ERROR_BUSY | Ключевой контейнер с данным именем был создан иным процессом и в настоящее время не может использоваться данным поцессом. Если эта ошибка возникает при обработке контейнера в одном процессе, разрешить коллизию можно вызвав функцию CPReleaseContext().
NTE_BAD_FLAGS | Некорректное значение параметра dwFlags.
NTE_BAD_KEYSET | Ключевой контейнер не был открыт или не существует.
NTE_BAD_KEYSET_PARAM | Используется некорректное значение параметра pszContainer. Ошибка также может возникнуть при открытии с флагом CRYPT_SILENT и неоднозначности в выборе носителя.
NTE_BAD_SIGNATURE | Не прошла проверка цифровой подписи DLL криптопровайдера. DLL или цифровая подпись искажены.
NTE_EXISTS | Параметр dwFlags установлен в CRYPT_NEWKEYSET, а ключевой контейнер уже существует.
NTE_KEYSET_ENTRY_BAD | Ключевой контейнер, соответствующий pszContainer найден, но искажён.
NTE_KEYSET_NOT_DEF | Ключевой контейнер, соответствующий pszContainer, не существует.
NTE_NO_MEMORY | Криптопровайдер во время операции исчерпал память.
NTE_TOKEN_KEYSET_STORAGE_FULL | Недостаточно места на носителе для сохранения информации.
NTE_SILENT_CONTEXT | Операция не может быть выполнена без пользовательского интерфейса.
SCARD_W_REMOVED_CARD | Носитель контейнера был удалён из считывателя.
SCARD_W_CANCELLED_BY_USER | Пользователь прервал операцию.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCAcquireContext .

См. также

CPReleaseContext() ,CPAcquireContext в MS CSP World Wide Web link ,CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link ,CryptSetProvParam в MS CryptoAPI 2.0 World Wide Web link


CPReleaseContext

Функция CPReleaseContext() используется для удаления дескриптора криптопровайдера, созданного CPAcquireContext().

BOOL WINAPI CPReleaseContext(
  HCRYPTPROV hProv,
  DWORD dwFlags
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
dwFlags
[in] Значения флагов. Параметр зарезервирован для будущего использования и должен быть нулевым.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возврата | Описание
NTE_BAD_FLAGS | Параметр dwFlags имеет ненулевое значение.

Примечания

После того, как эта функция была вызвана, дескриптор hProv становится недействительным. Сессионные ключи и объекты функции хэширования, созданные с использованием дескриптора hProv, удаляются. Рекомендуется, чтобы приложение делало это заранее с использованием функций CPDestroyKey() и CPDestroyHash().

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCReleaseContext .

См. также

CPAcquireContext() ,CPReleaseContext в MS CSP World Wide Web link ,CryptReleaseContext в MS CryptoAPI 2.0 World Wide Web link


CPGetProvParam

Функция CPGetProvParam() получает параметры криптопровайдера.

BOOL WINAPI CPGetProvParam(
  HCRYPTPROV hProv,
  DWORD dwParam,
  BYTE * pbData,
  DWORD * pdwDataLen,
  DWORD dwFlags
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
dwParam
[in] Значение, определяющее тип возвращаемых данных. В настоящее время определены следующие значения параметра dwParam.
Значение dwParam | Содержимое буфера pbData
PP_CACHE_SIZE | Настройки кэширования контейнеров в виде структуры CRYPT_CACHE_SIZE .
PP_CONTAINER | Имя ключевого контейнера вида CONTAINER, если он имеет имя, в противном случае уникальное имя (см. PP_UNIQUE_CONTAINER). Строка, заканчивающаяся нулем, содержащая имя текущего ключевого контейнера. Подробнее см. Дополнительные параметры и определения .
PP_UNIQUE_CONTAINER | Уникальное имя ключевого контейнера, которое включает тип ключевого носителя и может иметь вид: MEDIA\FOLDER, MEDIA\UNIQUE\FOLDER или MEDIA\UNIQUE. Строка, заканчивающаяся нулем, содержащая имя текущего ключевого контейнера. Подробнее см. Дополнительные параметры и определения .
PP_ENUMALGS | Поддерживаемые алгоритмы. Подробнее см. CryptGetProvParam в MS CryptoAPI 2.0 World Wide Web link .
PP_ENUMALGS_EX | Поддерживаемые алгоритмы. Подробнее см. CryptGetProvParam в MS CryptoAPI 2.0 World Wide Web link .
PP_ENUMCONTAINERS | Имя одного из ключевых контейнеров, которые могут быть использованы криптопровайдером, возвращаемое в форме строки, заканчивающейся нулем. Прикладные программы могут вызывать функцию с данным параметром последовательно для перечисления всех ключевых контейнеров, поддерживаемых криптопровайдером. Эта функция не является многопоточной, и поэтому при использовании ее в многопоточном контексте есть вероятность, что не все поддерживаемые ключевые контейнеры будут перечислены.
PP_PROVTYPE | Тип криптопровайдера. Возвращается в виде переменной типа DWORD.
PP_IMPTYPE Тип реализации криптопровайдера. Возвращается в виде переменной типа DWORD. В настоящее время определены следующие типы реализации:
  • CRYPT_IMPL_HARDWARE
  • CRYPT_IMPL_SOFTWARE
  • CRYPT_IMPL_MIXED
  • CRYPT_IMPL_UNKNOWN
  • CRYPT_IMPL_REMOVABLE
PP_HANDLE_COUNT | Количество используемых хэндлов. Должен быть установлен параметр dwFlags. При значении dwFlags = 0, текущее количество. При значении dwFlags = 1, максимальное. Возвращается в виде переменной типа DWORD.
PP_NAME | Имя провайдера в форме строки, заканчивающейся нулем. Это имя соответствует "CSP Name", которое программа setup установила в Windows® Registry.
PP_VERSION | Версия криптопровайдера. Возвращается в виде переменной типа DWORD. Например, версия 1.0 представляется как 0x00000100.
PP_VERSION_EX | Возвращает версию ядра криптопровайдера в виде структуры PROV_PP_VERSION_EX .
PP_KEYSPEC | Тип ключа (всегда либо AT_KEYEXCHANGE, либо AT_SIGNATURE, либо AT_UECSYMMETRICKEY). Возвращается в виде переменной типа DWORD.
PP_KEYX_KEYSIZE_INC | Размер модуля открытого ключа обмена AT_KEYEXCHANGE. Возвращается в виде переменной типа DWORD. Размер модуля ключа равен 512 (для ГОСТ Р 34.10-2001).
PP_SIG_KEYSIZE_INC | Размер модуля открытого ключа ЭП AT_SIGNATURE. Возвращается в виде переменной типа DWORD. Размер модуля ключа равен 512 (для ГОСТ Р 34.10-2001).
PP_KEYSET_SEC_DESCR | Возвращает дескриптор безопасности раздела реестра Windows, где хранятся ключи пользователя.
PP_KEYSET_TYPE | Определяет, является ли hProv контекстом ключа компьютера или пользователя. Возвращает DWORD со значением CRYPT_MACHINE_KEYSET, если этот флаг был передан в CPAcquireContext(), или 0 в противном случае.
PP_KEYSTORAGE | Возвращает DWORD со значением CRYPT_SEC_DESCR.
PP_ENUMOIDS_EX | Поддерживаемые идентификаторы криптографических параметров алгоритмов. Перечисляются строковые величины - OID криптографических параметров алгоритмов.
PP_HASHOID | OID текущих параметров алгоритма функции хэширования.
PP_SIGNATUREOID | OID текущих параметров алгоритма подписи в зависимости от типа провайдера.
PP_DHOID | OID текущих параметров алгоритма Диффи-Хеллмана в зависимости от типа провайдера.
PP_CIPHEROID | OID текущих параметров алгоритма шифрования.
PP_CHECKPUBLIC | Передаёт в pbData значение флага проверки открытого ключа.
PP_RANDOM | Возвращает в pbData последовательность случайных чисел для установки программного ДСЧ криптопровайдера уровня ядра ОС. Если контекст криптопровайдера hProv открыт в режиме CRYPT_VERIFYCONTEXT, то предварительно будут получены случайные числа с физического или клавиатурного ДСЧ. См. описание параметра PP_USE_HARDWARE_RNG CPSetProvParam().
PP_ENUM_HASHOID | Получает перечень идентификаторов криптографических объектов, связанных с функцией хэширования.
PP_ENUM_CIPHEROID | Получает перечень идентификаторов криптографических объектов, связанных с функцией шифрования.
PP_ENUM_SIGNATUREOID | Получает перечень идентификаторов криптографических объектов, связанных с функцией цифровой подписи, в зависимости от типа провайдера.
PP_ENUM_DHOID | Получает перечень идентификаторов криптографических объектов, связанных с алгоритмом Диффи-Хеллмана, в зависимости от типа провайдера.
PP_HCRYPTPROV | Загружает контейнер в память и возвращает DWORD идентифицирующий контейнер.
PP_SELECT_CONTAINER | Выводит диалоговое окно выбора контейнера и возвращает имя выбраного пользователем контейнера. Если dwFlags & CRYPT_FQCN, то имя контейнера возвращается в формате FQCN (см. PP_FQCN). Имя контейнера возвращается в текущей кодировке. Возвращаемая строка заканчивается нулем.
PP_FQCN | Возвращает FQCN (Fully Qualified Container Name) конетйнера: \\.\<Reader>\<Name>, где <Reader> имя считывателя, на котором находится контейнер, <Name> имя контейнера в текущей кодировке. Возвращаемая строка заканчивается нулем.
PP_ENUMREADERS | Информация об одном из считывателей ключевых контейнеров, которые могут быть использованы криптопровайдером. Если dwFlags не содержит специальных значений, то в виде сериализованной псевдоструктуры CRYPT_ENUMREADER_INFO . Если dwFlags & CRYPT_MEDIA, то в виде сериализованной псевдоструктуры CRYPT_ENUMREADER_INFO_MEDIA . Прикладные программы могут вызывать функцию с данным параметром последовательно для перечисления всех ключевых контейнеров, поддерживаемых криптопровайдером. Эта функция не является многопоточной, и поэтому при использовании ее в многопоточном контексте есть вероятность, что не все поддерживаемые считыватели будут перечислены.
PP_INFO | Вовращает структуру, содержащую значение таймера криптографического модуля, для недрайвера дополнительно содержит количество ДСРФ, свободное место на файловой системе /var, количество попыток выпусть ключ УЛ, количество успешных смен карт канала "К", количество карт канала выпущенных при последней смене, количество операций подписи
PP_PIN_INFO | Возвращает структуру пароля для текущего контейнера в виде структуры CRYPT_PIN_INFO
PP_PASSWD_TERM | Получает термин пароль ("пароль" / "pin-code") для текущего носителя. Возвращаемое значение содержит строку текущей кодировке заканчивающуюся нулем.
PP_SAME_MEDIA | Провека наличия носителя, соответствующего данному контейнеру, в считывателе. Возвращает TRUE, если носитель есть. FALSE и код ошибки SCARD_W_REMOVED_CARD, если отсутствует. Буфер pbData не используется.
PP_VERSION_TIMESTAMP | Получение даты и времени завершения компиляции в формате "day month year" "hh:mm:ss".
PP_SECURITY_LEVEL | Возвращает DWORD уровня сертификации данного криптографического модуля KC1: 1, KC2: 2, KC3: 3, KB1: 4, KB2: 5, KA1: 6
PP_FAST_CODE_FLAGS

Параметр предназначен для определения, какой код - быстрый или медленный - используется в провайдере на компьютерах, оснащенных процессором Intel Pentium 4. В pbData возвращается DWORD с флагами CSP_FAST_CODE_*. Параметр dwFlags должен содержать хотя бы один из флагов, указанных ниже.

Флаги для определения списка проверяемых функций.
CRYPT_FAST_CODE_ALL_KERNEL_FUNCTIONS - запрос кода функций провайдера уровня ядра ОС.
CRYPT_FAST_CODE_ALL_USER_FUNCTIONS - запрос кода функций провайдера уровня пользователя.
CRYPT_FAST_CODE_ALL_FUNCTIONS - запрос кода всех функций провайдера.
CRYPT_FAST_CODE_GET_SETFN - запроса результата работы функции определения процессора.

PP_ENUM_CONTAINER_EXTENSION | Имя одного из расширений ключевого контейнера, возвращаемое в форме структуры CONTAINER_EXTENSION. Прикладные программы могут вызывать функцию с данным параметром последовательно для перечисления всех расширений ключевого контейнера. Эта функция не является многопоточной, и поэтому при использовании ее в многопоточном контексте есть вероятность, что не все поддерживаемые считыватели будут перечислены.
PP_SELFTEST | [TODO:XX] Документация предварительная. [TODO:XX] Вызывает функцию самотестирования и контроля целостности. Для dwFlags равного нулю, тестируется оконечное СКЗИ. Результат возвращается в виде структуры PROV_PP_SELFTEST . При установке флага CP_CRYPT_SET_TESTER_STATUS устанавливается статус самотестирования. При установке флага CP_CRYPT_SELFTEST_FORCE_FAIL форсируется ошибка. При установке флага CP_CRYPT_SELFTEST_FORCE_SUCCESS форсируется успех.
PP_EXCHANGE_KEY_FP | Возвращает первые 8 байт открытого ключа обмена. Если в контейнере нет ключа обмена, функция возвращает FALSE.
PP_SIGNATURE_KEY_FP | Возвращает первые 8 байт ключа проверки подписи. Если в контейнере нет ключа подписи, функция возвращает FALSE.
pbData
[out] Указатель на буфер, содержащий данные параметра. Функция копирует соответствующие параметру данные в буфер. Формат этих данных зависит от значения dwParam. Если аргумент функции - NULL, то данные не копируются. Требуемый размер буфера в байтах возвращается в pdwDataLen. Подробнее см. Возвращение данных неопределенной длины. Как отмечено в CryptGetProvParam в MS CryptoAPI 2.0 World Wide Web link , когда читается один из параметров перечисления, возвращенное в pdwDataLen значение будет равно размеру самого большого элемента в списке перечисления.
pdwDataLen
[in/out] Указатель на буфер, содержащий длину данных параметра. При вызове функции указанный аргумент содержит размер передаваемого буфера pbData в байтах. После возврата из неё pbData содержит число байтов данных параметра, скопированных в буфер pbData. Если буфер, соответствующий pbData, недостаточно велик, чтобы в него копировать запрошенные данные, через функцию GetLastError будет возвращён код ошибки ERROR_MORE_DATA. В этом случае требуемый размер буфера возвращается в pdwDataLen. Если эта функция завершается с кодом ошибки, отличным от ERROR_MORE_DATA, в этом аргументе возвращается ноль.
dwFlags
[in] Значения флагов. В настоящее время определены следующие значения флагов:
Значение dwFlags | Описание
CRYPT_FIRST | Используется совместно с параметром перечисления (например, PP_ENUMALGS, PP_ENUMALGS_EX или PP_ENUMCONTAINERS). При использовании этого флага возвращается первый элемент в списке перечисления, в противном случае возвращается следующий элемент в списке. Если флаг используется совместно с параметром, не являющимся параметром перечисления, то возвращается код ошибки NTE_BAD_FLAGS.
CRYPT_UNIQUE | Используется совместно с параметром PP_ENUMCONTAINERS. При использовании этого флага первыми по приоритету перед обычными именами возвращаются уникальные имена контейнеров. Если под уникальный номер выделено достаточно памяти, после уникального номера копируется обычное имя контейнера.
CRYPT_FQCN | Используется совместно с параметром PP_ENUMCONTAINERS, PP_SELECT_CONTAINER. При использовании этого флага имя контейнера возвращается в формате FQCN (см. PP_FQCN). Имя контейнера возвращается в текущей кодировке. Возвращаемая строка заканчивается нулем.
SECURITY_INFORMATION Если dwParam установлен в PP_KEYSET_SEC_DESCR, будет возвращен дескриптор безопасности раздела реестра, содержащего ключевой контейнер. В этом случае dwFlags используется, чтобы передать битовые флаги, объединяемые поразрядной операцией OR. Указатель на дескриптор безопасности возвращается в аргументе pbData, длина дескриптора безопасности возвращается в аргументе pcbData. Для получения дополнительной информации, см. RegGetKeySecurity и RegSetKeySecurity. Следующий список содержит определённые битовые маски, используемые для возврата требуемой информации.
  • OWNER_SECURITY_INFORMATION - Указывает идентификатор владельца упомянутого объекта.
  • GROUP_SECURITY_INFORMATION - Указывает идентификатор первичный группы упомянутого объекта.
  • DACL_SECURITY_INFORMATION - Указывает идентификатор дискреционного ACL упомянутого объекта.
  • SACL_SECURITY_INFORMATION - Указывает идентификатор системного ACL упомянутого объекта.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError.
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
ERROR_MORE_DATA | Размер буфера pbData недостаточен для копирования затребованных данных.
ERROR_NO_MORE_ITEMS | Достигнут конец списка перечисления. Данные в буфере pbData непригодны. Данный тип ошибки может возвращаться, только если dwParam имеет значение PP_ENUMALGS, PP_ENUMALGS_EX, PP_ENUMCONTAINERS, PP_ENUMOIDS_EX, PP_ENUM_HASHOID, PP_ENUM_CIPHEROID, PP_ENUM_SIGNATUREOID, PP_ENUM_DHOID, или PP_ENUMREADERS.
NTE_BAD_FLAGS | Параметр dwFlags имеет некорректное значение.
NTE_BAD_TYPE | dwParam определяет неизвестный параметр.
SCARD_W_CANCELLED_BY_USER | Пользователь прервал операцию нажатием клавиши Cancel.
SCARD_W_WRONG_CHV | Пользователь ввёл неправильный пароль или пароль, установленный функцией SetProvParam, неправильный.
SCARD_E_INVALID_CHV | Пользователь ввёл пароль с нарушением формата или пароль, установленный функцией SetProvParam, имеет неправильный формат. Например, пароль имеет недопустимую длину или содержит недопустимые символы.
SCARD_W_CHV_BLOCKED | Ввод Pin-кода был заблокирован смарт-картой, т.к. исчерпалось количество попыток, разрешенное картой для ввода.
NTE_SILENT_CONTEXT | Операция не может быть выполнена без пользовательского интерфейса.
SCARD_W_REMOVED_CARD | Носитель контейнера был удален из считывателя.
NTE_BAD_SIGNATURE | Встроенный тест и/или контроль целостности СКЗИ выдал ошибку. Результаты находятся по адресу pbData, в виде структуры PROV_PP_SELFTEST .

Примечания

При указании параметра PP_SIGNATUREOID или PP_DHOID выбирается параметр, соответствующий типу провайдера. При указании параметра PP_ENUM_SIGNATUREOID или PP_ENUM_DHOID выбор соответствующего перечня идентификаторов производится аналогично.

PP_CIPHEROID для PROV_GOST_2001_DH по умолчанию равен "1.2.643.2.2.31.1", вариант "Верба-О"; для PROV_GOST_2012_256 или PROV_GOST_2012_512 равен "1.2.643.7.1.2.5.1.1", вариант ТК26 Z.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCGetProvParam .

См. также

CPAcquireContext() ,CPSetProvParam() ,CPGetProvParam в MS CSP World Wide Web link ,CryptGetProvParam в MS CryptoAPI 2.0 World Wide Web link


CPSetProvParam

Функция CPSetProvParam() устанавливает параметры криптопровайдера.

BOOL WINAPI CPSetProvParam(
  HCRYPTPROV hProv,
  DWORD dwParam,
  BYTE * pbData,
  DWORD dwFlags
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
dwParam
[in] Аргумент, принимающий следующие значения:
Значение dwParam | Содержимое буфера pbData
PP_CACHE_SIZE | Устанавливает настройки кэширования контейнеров. В pbData структура типа CRYPT_CACHE_SIZE .
PP_ENCRYPTION_CARRIER | Установить носитель как ключ шифрования контейнеров. Параметр pbData не используется.
PP_KEYSET_SEC_DESCR | Устанавливает дескриптор безопасности раздела реестра Windows, где хранятся ключи пользователя. Значение дескриптора передаётся в pbData.
PP_HASHOID | Устанавливает идентификатор алгоритма функции хэширования.
PP_CIPHEROID | Устанавливает идентификатор алгоритма шифрования.
PP_SIGNATUREOID | Устанавливает идентификатор алгоритма подписи в зависимости от типа провайдера.
PP_DHOID | Устанавливает идентификатор алгоритма Диффи-Хеллмана в зависимости от типа провайдера.
PP_KEYEXCHANGE_PIN Задаёт пароль (PIN) для доступа к ключам AT_SIGNATURE и AT_KEYEXCHANGE. Если пароль не задан этой функцией или задан этой функцией неверно, то он запрашивается у пользователя посредством UI перед первым обращением к носителю (если не был установлен флаг CRYPT_SILENT, см. CPAcquireContext()). Если pbData - NULL, то существующий пароль для этого контейнера забывается и для доступа к ключу потребуется повторный ввод пароля.

В "КриптоПро CSP 4.0" используется единый пароль (PIN) для доступа к ключам AT_SIGNATURE и AT_KEYEXCHANGE. Параметры PP_KEYEXCHANGE_PIN и PP_SIGNATURE_PIN эквивалентны.
PP_SIGNATURE_PIN Задаёт пароль (PIN) для доступа к ключам AT_SIGNATURE и AT_KEYEXCHANGE. Если пароль не задан этой функцией или задан этой функцией неверно, то он запрашивается у пользователя посредством UI перед первым обращением к носителю (если не был установлен флаг CRYPT_SILENT, см. CPAcquireContext()). Если pbData - NULL, то запомненный ранее пароль для этого контейнера забывается и для доступа к ключу потребуется повторный ввод пароля.

В "КриптоПро CSP 4.0" используется единый пароль (PIN) для доступа к ключам AT_SIGNATURE и AT_KEYEXCHANGE. Параметры PP_KEYEXCHANGE_PIN и PP_SIGNATURE_PIN эквивалентны.
PP_CHANGE_PIN | Задаёт новый пароль для контейнера hProv.
PP_SET_PIN | Устанавливает пароль на контейнер hProv в случае зашифрования его на другом контейнере или на нескольких контейнерах для схемы n из k. Этот пароль будет использован при последующем открытии контейнера hProv на чтение. Если контейнер hProv был создан при помощи функции CPAcquireContext() с флагом CRYPT_NEWKEYSET, то пароль, устанавливаемый на него, также будет установлен на доступ к ключу этого контейнера. Если функция CPSetProvParam() не вызывалась, то при доступе к ключу выдается UI (если не был установлен флаг CRYPT_SILENT, см. CPAcquireContext()). При открытии контейнера в SILENT-режиме возвращается ошибка.
PP_USE_HARDWARE_RNG Инициирует добавление к ДСЧ контекста криптопровайдера hProv значения с физического или БиоДСЧ. В случае, если в данной системе поддерживается только БиоДСЧ, то выдаётся UI для ввода событий мыши и/или клавиатуры (если не был установлен флаг CRYPT_SILENT, см. CPAcquireContext()).

При вызове функции CPSetProvParam() с параметром PP_USE_HARDWARE_RNG параметр pbData не используется.

Обычно, при отсуствии в системе физического ДСЧ, данные с БиоДСЧ добавляются в обязательном порядке к контексту криптопровайдера (в контейнер ключевой информации) только при создании постоянных ключей AT_KEYEXCHANGE или AT_SIGNAUTURE функцией CPGenKey().
PP_RANDOM | Устанавливает в pbData ключевой блоб типа SIMPLEBLOB (см. CRYPT_SIMPLEBLOB ), содержащий последовательность случайных чисел, необходимую для установки программного ДСЧ уровня ядра ОС. См. описание параметра PP_RANDOM функции CPGetProvParam().
PP_CHECKPUBLIC | Получает из pbData значение флага проверки открытого ключа. Если значение pbData типа DWORD равно 1, при импорте открытого ключа проверяется его корректность, если 0, проверка производится, если флаг установлен по параметру PP_ADMIN_CHECKPUBLIC. Открытый ключ, соответствующий ГОСТ 34.10-2001, проверяется всегда.
PP_ADMIN_CHECKPUBLIC | Получает из pbData значение флага проверки открытого ключа и устанавливает его в реестр. Если значение установленного в реестре флага равно 1, при импорте открытого ключа проверяется его корректность независимо от установки пользователя по параметру PP_CHECKPUBLIC, если значение установленного в реестре флага равно 0, проверка производится в зависимости от установки по параметру PP_CHECKPUBLIC. Открытый ключ, соответствующий ГОСТ 34.10-2001, проверяется всегда.
PP_FAST_CODE_FUNCS | Параметр предназначен для управления подключением быстрых функций на на процессорах с архитектурой ia32/amd64. Применяется для установки функций захвата и освобождения регистров расширений MMX/SSE2/SSSE3/AVX. Определён только в KC1 без сервиса хранения ключей. Для управления в остальных режимах см. CPC_FAST_CODE . В многопоточном окружении следует учитывать, что изменяет настройки всего СКЗИ (HCRYPTMODULE) и должна выполнятся, в общем случае, при том условии, что нет открытых контекстов ключей и/или ключей. В режиме ядра, при установке CPC_FAST_CODE_USER и нулевых указателях на функции захвата/освобождения FPU, они не изменяются. В pbData структура типа CPC_FAST_CODE .
PP_NK_SYNC | Производит запись одной из частей контейнера разделенного по схеме K из N. В качестве pbData должен быть передан DWORD полученный функцией GetProvParam с параметром PP_HCRYPTPROV. Функция используется для создания контейнера разделенного на части без выдачи окон.
PP_DELETE_KEYSET | Удаляет текущий контейнер с носителя. Функция используется для удаления контейнеров, требующих для очистки пароля, в SILENT режиме. Контейнер после успешного завершения данной операции больше не может быть использован ни в одной функции провайдера, исключая CPReleaseContext (CryptReleaseContext).
PP_DELETE_SAVED_PASSWD | Удаляет сохраненные на диске пароли для текущего контейнера. Если контекст открыт с флагом CRYPT_VERIFYCONTEXT, то будут удалены сохраненные пароли на все контейнеры.
PP_CONTAINER_EXTENSION | Устанавливает extension для контейнера. Если extension уже был задан в контейнере, то функция заменяет этот extension в контейнере. В качестве pbData должен быть передан extension в формате CERT_EXTENSION.
PP_CONTAINER_EXTENSION_DEL | Удаляет из контейнера extension, заданный строковым представлением OID.
PP_CONTAINER_DEFAULT | Устанавливает текущий контейнер - контейнером по умолчанию на текущем носителе.
PP_DELETE_SHORTCUT | Удаляет сохраненные на диске shortcut для заданного параметром контейнера или для всех контейнеров. Если в качестве pbData передан NULL, то функция производит удаление всех сохраненных shortcut. Если в качестве pbData передано имя контейнера, то функция удаляет сохраненный shortcut для этого контейнера. Имя контейнера должно быть задано в текущей кодировке и заканчиваться нулем. В качестве имени нельзя передавать уникальное имя контейнера и имя в формате FQCN (Fully Qualified Container Name).
pbData
[in] Указатель на буфер, содержащий данные параметра. Этот буфер при обращении к функции должен содержать данные, которые соответствуют типу параметра, помещённому в dwParam. Формат данных зависит от типа параметра.
dwFlags
[in] Значения флагов. Используются следующие значения флагов:
Значение dwFlags Описание
SECURITY_INFORMATION Флаг устанавливается, если dwParam установлен в дескриптор безопасности раздела реестра PP_KEYSET_SEC_DESCR,содержащего ключевой контейнер. Указатель на дескриптор безопасности передаётся в аргументе pbData, его длина передаётся в аргументе pcbData. Используются следующие битовые флаги:
  • OWNER_SECURITY_INFORMATION - Указывает идентификатор владельца объекта.
  • GROUP_SECURITY_INFORMATION - Указывает идентификатор первичный группы объекта.
  • DACL_SECURITY_INFORMATION - Указывает идентификатор дискреционного ACL объекта.
  • SACL_SECURITY_INFORMATION - Указывает идентификатор системного ACL объекта.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError.
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_DATA | Длина идентификатора главного ключа пользователя превышает максимально допустимую. Если функция вызывалась с PP_FAST_CODE_FUNCS, ошибка в заданном размере буфера для сохранения регистров.
NTE_BAD_FLAGS | Величина dwFlags имеет ненулевое значение.
NTE_BAD_TYPE | dwParam определяет неизвестный параметр.
NTE_KEYSET_ENTRY_BAD | Нарушение целостности ключей в ОЗУ.
NTE_FAIL | Ошибка при считывании данных из системного реестра.
SCARD_W_CANCELLED_BY_USER | Пользователь прервал операцию нажатием клавиши Cancel
SCARD_W_WRONG_CHV | Пользователь ввёл неправильный пароль или пароль, установленный функцией SetProvParam, неправильный
SCARD_E_INVALID_CHV | Пользователь ввёл пароль с нарушением формата или пароль, установленный функцией SetProvParam(), имеет неправильный формат. Например, пароль имеет недопустимую длину или содержит недопустимые символы.
SCARD_W_CHV_BLOCKED | Ввод Pin-кода был заблокирован смарт-картой, т.к. исчерпалось количество попыток разрешенное картой для ввода.
NTE_TOKEN_KEYSET_STORAGE_FULL | Недостаточно места на носителе для сохранения информации.
NTE_SILENT_CONTEXT | Операция не может быть выполнена без пользовательского интерфейса.
SCARD_W_REMOVED_CARD | Носитель контейнера был удален из считывателя

Примечания

При указании параметра PP_SIGNATUREOID или PP_DHOID выбирается параметр, соответствующий типу провайдера.

Устанавливаемые с помощью PP_DHOID/PP_SIGNATUREOID идентификаторы параметров закрытых ключей определяют данные параметры только для долговременных ключей и эфемерных ключей, тип которых соответствует типу провайдера. Для эфемерных ключей, тип которых не соответствует типу провайдера, идентификаторы параметров необходимо указывать явно с помощью функции CPSetKeyParam().

Пример установки PIN на контейнер. Необходимо установить на контейнер с именем "test" PIN "12345".
HCRYPTPROV hProv;
BYTE PIN[6] = {'1', '2', '3', '4', '5', 0}; // Необходимо указывать признак конца строки - 0.
//Открываем контейнер
CPAcquireContext(&hProv, "test", 0, pVTable);
//Устанавливаем PIN
CPSetProvParam(hProv, PP_SIGNATURE_PIN, PIN, 0);
//PIN установлен.
В случае, если непосредственно установить PIN в текущем контексте невозможно, необходимо повторно открыть контекст контейнера и установить PIN в новом контексте.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCSetProvParam .

См. также

CPAcquireContext() ,CPGetProvParam() ,CPSetProvParam в MS CSP World Wide Web link ,CryptSetProvParam в MS CryptoAPI 2.0 World Wide Web link


Функции генерации и работы с ключами

Функции генерации и работы с ключами предназначены для генерации ключей и ключевых пар (закрытый/открытый ключи), а также для обработки различных типов ключей, используемых в криптопровайдере.

Функции | Описание
CPGenKey | Функция CPGenKey() генерирует случайные криптографические ключи или ключевую пару (закрытый/открытый ключи).
CPDestroyKey | Функция CPDestroyKey() удаляет ключ, передаваемый через параметр hKey. После удаления ключ (дескриптор ключа) не может использоваться.
CPDeriveKey | Функция CPDeriveKey() производит криптографические ключи сессии на основе значения хэш-функции, вычисленной по другим ключам, паролям или любым другим данным пользователя.
CPDuplicateKey | Функция CPDuplicateKey() создаёт точную копию заданного ключа, включая все его переменные, определяющие внутреннее состояние ключа (вектор IV, режим шифрования, режим преобразования, режим дополнения, набор узлов замены и прочее).
CPExportKey | Функция CPExportKey() используется для экспорта криптографических ключей из ключевого контейнера криптопровайдера, сохраняя их в защищённом виде.
CPGenRandom | Функция CPGenRandom() заполняет буфер случайными байтами.
CPGetKeyParam | Функция CPGetKeyParam() возвращает параметры ключа.
CPGetUserKey | Функция CPGetUserKey() возвращает дескриптор одной из долговременных ключевых пар в ключевом контейнере.
CPImportKey | Функция CPImportKey() используется для импорта криптографического ключа из ключевого блоба в контейнер криптопровайдера, для диверсификации ключа с использованием данных, передаваемых через ключевой блоб в соответствии с RFC 4357, п. 7., а так же для диверсификации ключа в соответствии с алгоритмами, описанным в п. 4.4, 4.5 рекомендаций по стандартизации "Криптографические алгоритмы, сопутствующие применению алгоритмов электронной цифровой подписи и функции хэширования".
CPSetKeyParam | Функция CPSetKeyParam() устанавливает параметры ключа.


CPGenKey

Функция CPGenKey() генерирует случайные криптографические ключи или ключевую пару (закрытый/открытый ключи).

BOOL WINAPI CPGenKey(
  HCRYPTPROV hProv,
  ALG_ID AlgId,
  DWORD dwFlags,
  HCRYPTKEY * phKey
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
AlgId
[in] Идентификатор алгоритма шифрования или ЭП, для которого производится ключ. Могут быть произведены ключи следующих классов:
  • временные симметричные ключи (сессионные ключи);
  • временные (эфемерные) ключевые пары алгоритмов Диффи-Хеллмана;
  • долговременные ключевые пары, сохраняемые в ключевом контейнере.

    Возможные сессионные ключи:
    Значение AlgId | Описание
    CALG_G28147 | Ключ шифрования и/или имитозащиты данных по ГОСТ 28147-89. В последствии этот ключ можно пометить как ключ для импорта/экспорта с помощью функции CPSetKeyParam().
    CALG_TLS1_MASTER | Специальный ключ для реализации протокола TLS.
    Возможные эфемерные ключи Диффи-Хеллмана:
    AlgId | Описание
    CALG_UECSYMMETRIC_EPHEM | Эфемерный симметричный ключ. Предназначен для управления ключами в системе Универсальная электронная карта.
    CALG_DH_EL_EPHEM | Эфемерная ключевая пара на базе ГОСТ Р 34.10-2001. Предназначена для обмена сессионными ключами.
    CALG_DH_GR3410_12_256_EPHEM | Эфемерная ключевая пара на базе ГОСТ Р 34.10-2012 с длиной ключа 256 бит. Предназначена для обмена сессионными ключами.
    CALG_DH_GR3410_12_512_EPHEM | Эфемерная ключевая пара на базе ГОСТ Р 34.10-2012 с длиной ключа 512 бит. Предназначена для обмена сессионными ключами.
    Возможные долговременные ключевые пары:
    AlgId | Описание
    AT_KEYEXCHANGE | Производится ключевая пара, сохраняемая в ключевом контейнере. Предназначена для обмена сессионными ключами и ЭП. В качестве алгоритма ключевой пары выбирается алгоритм по умолчанию для hProv, параметр PP_DHOID функции CPGetProvParam().
    CALG_DH_EL_SF | Производится ключевая пара согласно ГОСТ Р 34.10-2001. Предназначена для обмена сессионными ключами и ЭП, в ключевой контейнер не заносится.
    CALG_DH_GR3410_12_256_SF | Производится ключевая пара согласно ГОСТ Р 34.10-2012 с длиной ключа 256 бит. Предназначена для обмена сессионными ключами и ЭП, в ключевой контейнер не заносится.
    CALG_DH_GR3410_12_512_SF | Производится ключевая пара согласно ГОСТ Р 34.10-2012 с длиной ключа 512 бит. Предназначена для обмена сессионными ключами и ЭП, в ключевой контейнер не заносится.
    AT_SIGNATURE | Производится ключевая пара, сохраняемая в ключевом контейнере. Предназначена для ЭП. В качестве алгоритма ключевой пары выбирается алгоритм по умолчанию для hProv, параметр PP_SIGNATUREOID функции CPGetProvParam().
    CALG_GR3410EL | Производится ключевая пара согласно ГОСТ Р 34.10-2001, в ключевой контейнер не заносится.
    CALG_GR3410_12_256 | Производится ключевая пара согласно ГОСТ Р 34.10-2012 с длиной ключа подписи 256 бит, в ключевой контейнер не заносится.
    CALG_GR3410_12_512 | Производится ключевая пара согласно ГОСТ Р 34.10-2012 с длиной ключа подписи 512 бит, в ключевой контейнер не заносится.
    AT_UECSYMMETRICKEY | Производится симметричный пользовательский ключ. Предназначен для использования как мастерключ в системе производства ключей карт. Заносится в ключевой контейнер.
    CALG_UECSYMMETRIC | Производится симметричный ключ. Если генерация ключа производится в именованном контексте, где нет ключа AT_UECSYMMETRICKEY, создаваемый ключ заносится в ключевой контейнер. Предназначен для использования как мастерключ в системе производства ключей карт. В ключевой контейнер заносится, если сответствующий AT_UECSYMMETRICKEY в ключевом контейнере отсутствует.
dwFlags
[in] Флаги определяют признаки производимого ключа. Размеры ключей подписи и ключей обмена могут быть установлены при выработке ключа. Размер ключа устанавливается в старших 16 битах параметра dwFlags, эти 16 бит представляют длину открытого ключа в битах. Длина открытого ключа равна 512 для ГОСТ Р 34.10-2001 и ГОСТ Р 34.10-2012, длина ключа подписи 256 бит, и 1024 для ГОСТ Р 34.11-2012, длина ключа подписи 512 бит. Если длина ключа указана явно, она должна строго соответствовать алгоритму ключа и типу используемого провайдера. В настоящее время определены следующие флаги:
Значение dwFlags | Описание
CRYPT_EXPORTABLE Если этот флаг установлен, то произведённый ключ может быть передан из криптопровайдера в ключевой блоб через функцию CPExportKey(). Если этот флаг не установлен, ключ не будет экспортируемым и будет доступен только в пределах текущей сессии приложению, которое создало этот ключ. Действие этого флага не распространяются на открытые ключи ключевых пар.

Экспорт закрытых ключей ключевых пар 2001 года возможен только на эфемерных ключах и ключах с алгоритмом CALG_PRO_EXPORT и CALG_PRO12_EXPORT. Экспорт закрытых ключей ключевых пар 2012 года возможен только на эфемерных ключах и ключах с алгоритмом CALG_PRO12_EXPORT.
CRYPT_USER_PROTECTED | Если этот флаг установлен, то при любом запросе на доступ к носителю закрытого ключа пользователя выводится окно диалога, запрашивающего право доступа к ключу.
CRYPT_PREGEN | Если этот флаг установлен, то генерируется "пустая" ключевая пара обмена. Параметры этой ключевой пары должны быть установлены с использованием функции CPSetKeyParam().
CP_CRYPT_DH_ALLOWED | Если этот флаг установлен, то закрытый ключ произведенной ключевой пары может быть использован для согласования сессионного ключа с помощью алгоритма Диффи-Хеллмана (VKO). Если данный флаг не указан, то для ключевых пар электронной подписи 2012 года согласование будет запрещено. Для ключевых пар обмена разрешено всегда.
phKey
[out] Адрес, по которому функция копирует дескриптор сформированного ключа (ключевой пары открытый/закрытый ключи).

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_ALGID | Параметр AlgId определяет алгоритм, не поддерживаемый криптопровайдером. Эта ошибка возвращается также в случае попытки генерации пользовательских ключей AT_KEYEXCHANGE и AT_SIGNATURE криптопровайдером, сертифицированным по уровню KC2 и выше, при отсутствии физического ДСЧ в составе СКЗИ.
NTE_BAD_FLAGS | Величина dwFlags имеет ошибочное значение.
NTE_NO_MEMORY | Криптопровайдер во время операции исчерпал память.
NTE_FAIL | Ошибка при считывании данных из системного реестра. см. Дополнительные параметры и определения .
SCARD_W_CANCELLED_BY_USER | Пользователь прервал операцию нажатием клавиши Cancel
SCARD_W_WRONG_CHV | Пользователь ввёл неправильный пароль или пароль, установленный функцией SetProvParam(), неправильный
SCARD_E_INVALID_CHV | Пользователь ввёл пароль с нарушением формата или пароль, установленный функцией SetProvParam(), имеет неправильный формат. Например, пароль имеет недопустимую длину или содержит недопустимые символы.
SCARD_W_CHV_BLOCKED | Ввод Pin-кода был заблокирован смарт-картой, т.к. исчерпалось количество попыток разрешенное картой для ввода.
NTE_TOKEN_KEYSET_STORAGE_FULL | Недостаточно места на носителе для сохранения информации.
NTE_SILENT_CONTEXT | Операция не может быть выполнена без пользовательского интерфейса.
SCARD_W_REMOVED_CARD | Носитель контейнера был удален из считывателя.
NTE_EXISTS | Попытка создания ключа в контейнере, где ключ уже существует.

Примечания

Если при запросе функции CPAcquireContext() был создан ключевой контейнер с признаком CRYPT_VERIFYCONTEXT, прикладные программы не могут создавать долговременные ключевые пары. В этом случае функция CPGenKey() возвращает код ошибки NTE_PERM. Когда ключи порождаются для симметричного шифрования, по умолчанию ключ будет установлен в шифратор в режиме гаммирования с обратной связью (CFB) со случайным начальным вектором. Эти параметры могут быть получены с использованием функции CPSetKeyParam() и частично изменены функцией CPSetKeyParam()

Функция CPGenKey() получает ключ с программного ДСЧ контекста криптопровайдера hProv, который инициализируется при выполнении функции CPAcquireContext() c накопленного в контейнере ключевого носителя состояния ДСЧ и установленного в системе физического ДСЧ. Криптопровайдер "КриптоПро CSP-ECC/TLS" гарантирует инициализацию состояния ДСЧ контейнера ключевого носителя с физического или, если нет физического, с БиоДСЧ.

В случае, если контекст криптопровайдера открыт в режиме CRYPT_VERIFYCONTEXT, и в системе не установлено физического ДСЧ, программный ДСЧ инициализируется с накапливаемого в реестре общесистемного состояния ДСЧ и накопленных состояний ДСЧ всех открытых ранее контейнеров ключевых носителей в рамках времени жизни разделяемой библиотеки "КриптоПро CSP 4.0". Для гарантированной инициализации программного ДСЧ с физического ДСЧ, в случае если ранее не открывались контейнеры ключевых носителей, следует использовать функцию CPSetProvParam() с флагом PP_USE_HARDWARE_RNG.

Функция CPGenKey() при выработке долговременных ключевых пар всегда использует физический ДСЧ. В случае, если контекст криптопровайдера hProv открыт в режиме CRYPT_SILENT (запрет UI, необходимый БиоДСЧ), и в системе не установлен физический ДСЧ, выдаётся ошибка.

Ключи AT_UECSYMMETRICKEY, CALG_UECSYMMETRIC, CALG_UECSYMMETRIC_EPHEM имеют ограниченный функционал, предназначены для использования в ключевых системах Универсальных Электронных Карт. Данные ключи не рекомендуется использоваться в иных системах.

Заметим, что, в соответствии с общепринятой мировой практикой, в качестве длины ключа при создании указывается именно длина открытого ключа, а не присутствующая в идентификаторах алгоритмов и oid'ах длина модуля, по которому производятся операции. В отличие от, например, алгоритма RSA (в реализациях которого открытая экспонента, как правило, фиксирована, а открытый ключ представляет собой модуль n), длина открытого ключа в стандартах подписи, основанных на операциях в группе точек эллиптической кривой (ECDSA, ГОСТ Р 34.10-2001, ГОСТ Р 34.10-2012), в два раза превосходит длину модуля.

При генерации ключа подписи/обмена выбор соответствующего алгоритма производится в зависимости от типа используемого провайдера. Провайдер типа PROV_GOST_2001_DH создает ключи в соответствии с алгоритмом ГОСТ Р 34.10-2001, используется функция хэширования в соответствии с ГОСТ Р 34.11-94. Провайдер типа PROV_GOST_2012_256 создает ключи длины 256 бит в соответствии с алгоритмом ГОСТ Р 34.10-2012, в качестве алгоритма хэширования использует алгоритм ГОСТ Р 34.11-2012 (256 бит). Провайдер типа PROV_GOST_2012_512 создает ключи длины 512 бит в соответствии с алгоритмом ГОСТ Р 34.10-2012, в качестве алгоритма хэширования использует алгоритм ГОСТ Р 34.11-2012 (512 бит).

При генерации сессионного ключа CALG_G28147 параметр KP_CIPHEROID полученного ключа по умолчанию принимает установленное для провайдера значение PP_CIPHEROID, либо, после загрузки ключей из контейнера с помощью CPGetUserKey(), oid параметров шифрования, установленный в этом контейнере.

Для создания эфемеральных ключей необходимого типа с определёнными параметрами алгоритма Диффи-Хеллмана необходимо: сгенерировать "пустую" ключевую пару командой CPGenKey(hProv, algId, CRYPT_PREGEN, &hKey); затем установить тип параметров алгоритмов Диффи-Хеллмана командой CPSetKeyParam(hProv, hKey, KP_DHOID, pbOIDdata, 0); после чего непосредственно выработать значение ключа с помощью команды CPSetKeyParam(hProv, hKey, KP_X, NULL, 0);

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCGenKey .

См. также

CPDestroyKey() ,CPExportKey() ,CPImportKey() ,CPGetKeyParam() ,CPSetKeyParam() ,CPReleaseContext() ,CPGenKey в MS CSP World Wide Web link ,CryptGenKey в MS CryptoAPI 2.0 World Wide Web link


CPDestroyKey

Функция CPDestroyKey() удаляет ключ, передаваемый через параметр hKey. После удаления ключ (дескриптор ключа) не может использоваться.

BOOL WINAPI CPDestroyKey(
  HCRYPTPROV hProv,
  HCRYPTKEY hKey
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
hKey
[in] Дескриптор удаляемого ключа.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возврата | Описание
NTE_BAD_KEY | Дескриптор удаляемого ключа hKey ошибочен.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCDestroyKey .

См. также

CPDeriveKey() ,CPGenKey() ,CPGetUserKey() ,CPDestroyKey в MS CSP World Wide Web link ,CryptDestroyKey в MS CryptoAPI 2.0 World Wide Web link


CPDeriveKey

Функция CPDeriveKey() производит криптографические ключи сессии на основе значения хэш-функции, вычисленной по другим ключам, паролям или любым другим данным пользователя.

BOOL WINAPI CPDeriveKey(
  HCRYPTPROV hProv,
  ALG_ID AlgId,
  HCRYPTHASH hBaseData,
  DWORD dwFlags,
  HCRYPTKEY * phKey
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
AlgId
[in] Идентификатор алгоритма шифрования, для которого производится ключ.
Значение AlgId | Описание
CALG_G28147 | Ключ шифрования и/или имитозащиты данных по ГОСТ 28147-89. Впоследствии этот ключ может быть преобразован с помощью функции CPSetKeyParam() в ключ, на котором возможен экспорт/импорт других ключей.
CALG_TLS1_ENC_KEY | Ключ шифрования на основе объекта TLS1_MASTER_HASH.
CALG_TLS1_MAC_KEY | Ключ имитозащиты на основе объекта TLS1_MASTER_HASH.
CALG_UECSYMMETRIC CALG_UECSYMMETRIC_EPHEM CALG_G28147 | Ключи различных типов на основе объекта CALG_UECMASTER_DIVERS. Если именованный ключевой контекст не содержит ключа AT_UECSYMMETRICKEY, ключ CALG_UECSYMMETRIC заносится в ключевой контейнер.
hBaseData
[in] Дескриптор объекта функции хэширования, используемый для обработки входных данных. Во время вызова функции объект хэша "закрывается".
Для ГОСТ Р 34.11-94 и ГОСТ Р 34.11-2012 (и HMAC-ов на их основе) проводится дополнение до размера блока (если требуется), исполняются шаговые функции для последнего блока (если требуется), для длины и для контрольной суммы.
Для ГОСТ 28147-89 в режиме имитовставки проводится дополнение до размера блока (если требуется), и исполняется шаговая функции для последнего блока (если требуется).
Расчёт хэш-функции может быть продолжен с помощью:
  • последующего вызова *SetHashParam(HP_OPEN, TRUE) для CSP 3.6 и выше;
  • предварительного вызова *DuplicateHash() - стандартный для Microsoft способ;
    Для хэш с алгоритмами CALG_MD5, CALG_SHA1, CALG_SHA_256, CALG_SHA_384, CALG_SHA_512, CALG_G28147_IMIT функция может отработать успешно, но значение ключа всегда будет неопределённым.
    Для хэш с алгоритмом CALG_SHAREDKEY_HASH функция вырабатывает очередную компоненту ключа.
    Для хэш с алгоритмом CALG_FITTINGKEY_HASH функция вырабатывает собранный из компонентов ключ при условии, что все компоненты собраны функцией *HashSessionKey().
dwFlags
[in] Флаги определяют признаки производимого ключа сессии. В настоящее время определены следующие значения флагов:
Значение dwFlags | Описание
CRYPT_EXPORTABLE | Если флаг установлен, то произведённый ключ может быть передан из криптопровайдера в ключевой блоб через функцию CPExportKey(). Если флаг не установлен, ключ не будет экспортируемым и будет доступен только в пределах текущей сессии приложению, которое создало этот ключ. Действие этого флага не распространяются на открытый ключ ключевых пары.
CRYPT_SERVER | Если при работе с TLS флаг установлен, то создаётся ключ шифрования сервера, если не установлен - создаётся ключ шифрования клиента.
CP_CRYPT_GETUPPERKEY | Если флаг установлен, то для ГОСТ Р 34.11-2012 512 бит (и HMAC-ов на его основе) функция будет использовать старшие 32 байта хэш-значения. Не может быть использован с другими алгоритмами.
phKey
[out] Адрес, по которому функция копирует дескриптор произведённого ключа.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError.
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_ALGID | Параметр AlgId определяет алгоритм, который не поддерживается криптопровайдером.
NTE_BAD_FLAGS | Величина dwFlags имеет ошибочное значение.
NTE_BAD_HASH | Дескриптор хэша ошибочен.
NTE_NO_MEMORY | Криптопровайдер во время операции исчерпал память.
NTE_FAIL | Ошибка при считывании данных из системного реестра. см. Дополнительные параметры и определения .

Примечания

Если на вход подаётся фиксированный набор данных, то функция создаёт один и тот же ключ. В этом случае создаваемый ключ можно использовать только для шифрования данных или экспорта ключей на ключевые носители. Использовать его для шифрования данных или экспорта ключей, помещаемых на диск или передаваемых по каналу связи, не рекомендуется.

Использование алгоритмов CALG_MD5, CALG_SHA_256, CALG_SHA_384, CALG_SHA_512 не входит в функционал СКЗИ КриптоПро CSP 4.0, относящийся к действию сертификата ФСБ.

Режимы шифрования, преобразования ключа, дополнения открытого текста до кратности блока, набор узлов замены для получаемого ключа устанавливаются такие же, как и для вновь созданного ключа (см. CPSetKeyParam()).

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCDeriveKey .

См. также

CPDestroyKey() ,CPGenKey() ,CPDeriveKey в MS CSP World Wide Web link ,CryptDeriveKey в MS CryptoAPI 2.0 World Wide Web link


CPDuplicateKey

Функция CPDuplicateKey() создаёт точную копию заданного ключа, включая все его переменные, определяющие внутреннее состояние ключа (вектор IV, режим шифрования, режим преобразования, режим дополнения, набор узлов замены и прочее).

BOOL WINAPI CPDuplicateKey(
  HCRYPTPROV hProv,
  HCRYPTKEY hKey,
  DWORD * pdwReserved,
  DWORD dwFlags,
  HCRYPTKEY * phKey
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
hKey
[in] Дескриптор исходного (копируемого) ключа. Возможно дублирование только ключей класса ALG_CLASS_DATA_ENCRYPT (см. CryptGetProvParam в MS CryptoAPI 2.0 World Wide Web link ).
pdwReserved
[in] Параметр зарезервирован для будущего использования и должен быть NULL.
dwFlags
[in] Параметр зарезервирован для будущего использования и должен быть нулевым.
phKey
[out] Адрес, по которому функция возвращает дескриптор скопированного ключа.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_KEY | Дескриптор исходного ключа ошибочен.
NTE_BAD_FLAGS | Параметр dwFlags имеет ненулевое значение.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCDuplicateKey .

См. также

CPDestroyKey() ,CPDuplicateKey в MS CSP World Wide Web link ,CryptDuplicateKey в MS CryptoAPI 2.0 World Wide Web link


CPExportKey

Функция CPExportKey() используется для экспорта криптографических ключей из ключевого контейнера криптопровайдера, сохраняя их в защищённом виде.

BOOL WINAPI CPExportKey(
  HCRYPTPROV hProv,
  HCRYPTKEY hKey,
  HCRYPTKEY hExpKey,
  DWORD dwBlobType,
  DWORD dwFlags,
  BYTE * pbData,
  DWORD * pdwDataLen
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
hKey
[in] Дескриптор экспортируемого ключа.
hExpKey
[in] Дескриптор ключа, на котором осуществляется криптографическая защита экспортируемого ключа. Необходимо, чтобы этот ключ был общим с получателем корреспонденции. Зашифрованные данные ключа помещаются в ключевой блоб, предназначенный для внешнего хранения и передачи по каналам связи. Алгоритмы функции экспорта ключей гарантируют, что только пользователь предназначения сможет использовать этот ключевой блоб. Для защиты ключа используется алгоритм, указанный при создании ключа экспорта. Если ключевой блоб не будет зашифрован (например, если тип ключевого блоба - PUBLICKEYBLOB), этот параметр должен быть нулевым.
dwBlobType
[in] Тип ключевого блоба, предназначенного для экспорта ключа. В настоящее время определены три типа ключевых блобов:
Тип | Использование
SIMPLEBLOB | Используется для транспортировки симметричных ключей CALG_G28147, CALG_UECSYMMETRIC. pbData указывает на структуру CRYPT_SIMPLEBLOB .
OPAQUEKEYBLOB | Используется для транспортировки ключа сессии с накопленным состоянием. pbData указывает на структуру CRYPT_OPAQUEBLOB .
PUBLICKEYBLOB | Используется для транспортировки открытых ключей. pbData указывает на структуру CRYPT_PUBLICKEYBLOB .
PRIVATEKEYBLOB | Используется для транспортировки закрытых ключей). pbData указывает на структуру CRYPT_PRIVATEKEYBLOB .
dwFlags
[in] Значения флагов. Должен быть нулевым во всех случаях за исключением экспорта ключевой пары в PUBLICKEYBLOB. В настоящее время определены следующие значения флагов:
Значение dwFlags | Описание
CRYPT_PUBLICCOMPRESS | Если флаг установлен, то отрытый ключ в PUBLICKEYBLOB представляется парой (x,b), где байт b равен 2, если координата y чётная и 3 в противном случае. Если флаг не установлен, то отрытый ключ в PUBLICKEYBLOB представляется координатами (x,y) точки эллиптической кривой.
CP_CRYPT_CALCULATE_PUBLIC_KEY | Если флаг установлен, то открытый ключ будет перевычислен даже при наличии сертификата.
pbData
[in] Указатель на буфер данных, в который функция копирует ключевой блоб. Если значение этого параметра NULL, функция устанавливает по адресу pdwDataLen значение необходимой длины буфера и возвращает TRUE.
pdwDataLen
[in/out] Указатель на буфер, содержащий длину ключевого блоба. При вызове функции указанный параметр содержит число байтов в буфере pbData. После выполнения функции параметр будет установлен числом байтов данных, скопированных в буфер pbData. Если буфер, соответствующий pbData, недостаточно большой, будет возвращен код ошибки ERROR_MORE_DATA через функцию SetLastError(). В этом случае требуемый размер буфера возвращается в pdwDataLen. Если эта функция завершается с кодом ошибки, отличным от ERROR_MORE_DATA, в этом параметре возвращается ноль.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
ERROR_MORE_DATA | Буфер pbData недостаточно большой, чтобы копировать затребованные данные.
NTE_BAD_FLAGS | Величина dwFlags имеет ненулевое значение.
NTE_BAD_KEY | Один или оба из ключей, указанных hKey и hExpKey, не действительны.
NTE_BAD_KEY_STATE | Попытка экспорта ключа, когда право экспорта криптопровайдером не предоставлено; попытка экспорта на ключе, для которого разрешение экспортировать не установлено.
NTE_BAD_TYPE | dwBlobType параметр определяет неизвестный тип блоба.
NTE_NO_MEMORY | Криптопровайдер во время операции исчерпал память.
NTE_FAIL | Ошибка при считывании данных из системного реестра. см. Дополнительные параметры и определения .
SCARD_W_CANCELLED_BY_USER | Пользователь прервал операцию.

Примечания

Обычно для согласования (экспорта/импорта) сессионного ключа применяют алгоритм Диффи-Хеллмана. В этом случае ключ парной связи (ключ экспорта/импорта сессионного ключа) порождается операцией импорта (см. CPImportKey()) открытого ключа получателя (отправителя) на ключевой паре отправителя (получателя). Следует учитывать, что при использовании эфемерных ключей аутентификация пользователей не обеспечивается. Для экспорта сессионного ключа следует выполнить следующие шаги:

  • Импорт блоба открытого ключа получателя на своей ключевой паре;
  • Экспорт сессионого ключа на ключе парной связи.

      ...
      CPGetUserKey(hProv, AT_KEYEXCHANGE, &hUserKey);
      ...
      CPGenKey(hProv, CALG_G28147, CRYPT_EXPORTABLE, &hSessionKey);
      ...
      CPImportKey(hProv, pbRecipentPublicKey, cbRecipentPublicKey, hUserKey, 0, &hExchKey);
      ALG_ID ke_alg = CALG_PRO_EXPORT;
      CPSetKeyParam(hProv, hExchKey, KP_ALGID, (LPBYTE)&ke_alg, 0);
      CPExportKey(hProv, hSessionKey, hExchKey, SIMPLEBLOB, 0, pbSessionKeyForRecipient, &cbSessionKeyForRecipient);
      ...

Для ключей 2012 в качестве алгоритма согласования сессионного ключа используется алгоритм VKO GOST R 34.10-2012-256 (на основе функции хэширования ГОСТ Р 34.11-2012-256). Для ключей 2001 используется алгоритм VKO GOST R 34.10-2001 (на основе функции хэширования ГОСТ Р 34.11-94).

PUBLICKEYBLOB длины 69 байт в настоящее время не может использоваться в составе сертификата открытого ключа. Блобы данного вида критичны к искажениям, поэтому должны использоваться в приложениях с контролем целостности.

Для экспорта сессионных ключей могут использоваться алгоритмы CALG_SIMPLE_EXPORT, CALG_PRO_EXPORT и CALG_PRO12_EXPORT. Долговременные ключи 2001 года могут быть экспортированы при помощи алгоритмов CALG_PRO_EXPORT и CALG_PRO12_EXPORT. К ключам 2012 года применим только алгоритм экспорта CALG_PRO12_EXPORT.

Для ключей 2012 года, которые используют параметры алгоритма ГОСТ 28147, отличные от параметров по умолчанию ("1.2.643.7.1.2.5.1.1", вариант ТК26 Z), идентификатор соответствующих параметров указывается в ключевом блобе. При использовании параметров по умолчанию идентификатор в блоб не записывается.

Если симметричный ключ использует параметры шифрования "1.2.643.7.1.2.5.1.1" (вариант ТК26 Z), то при экспорте данного ключа длина ключевого блоба будет больше, чем при использовании других параметров. Для обеспечения корректности работы с памятью рекомендуется предварительно запрашивать значение необходимой длины буфера для возвращаемых данных.

Рекомендуется, по возможности, при выработке открытых ключей двукратно производить выработку открытого ключа и осуществлять проверку равенства результатов.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCExportKey .

См. также

CPImportKey() ,CPExportKey в MS CSP World Wide Web link ,CryptExportKey в MS CryptoAPI 2.0 World Wide Web link


CPGenRandom

Функция CPGenRandom() заполняет буфер случайными байтами.

BOOL WINAPI CPGenRandom(
  HCRYPTPROV hProv,
  DWORD dwLen,
  BYTE * pbBuffer
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
dwLen
[in] Число байтов случайных данных, которые будут произведены.
pbBuffer
[in/out] Указатель на буфер, в который копируются случайные данные. Длина этого буфера в байтах передаётся параметром dwLen.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_FAIL RPE_FAIL_STATBUFFER | Неудовлетворительная статистика датчика случайных чисел, контролируемая при открытии контейнера. Эта ошибка носит вероятностный характер. Для корректно работающей программы вероятность возникновения ошибки не превышает 10^(-16).
NTE_FAIL RPE_FAIL_TESTBUFFER | Неудовлетворительная постоянно действующая статистика датчика случайных чисел. Эта ошибка носит вероятностный характер. Для корректно работающей программы вероятность возникновения ошибки не превышает 10^(-16).
NTE_KEYSET_ENTRY_BAD | Данные неверно считаны из системного реестра.

Примечания

Функция CPGenRandom() получает случайные числа с программного ДСЧ контекста криптопровайдера hProv, который инициализируется при выполнении функции CPAcquireContext() c накопленного в контейнере ключевого носителя состояния ДСЧ и установленного в системе физического ДСЧ.

В случае, если контекст криптопровайдера открыт в режиме CRYPT_VERIFYCONTEXT и в системе не установлено физического ДСЧ, программный ДСЧ инициализируется с накапливаемого в реестре общесистемного состояния ДСЧ и накопленных состояний ДСЧ всех открытых ранее контейнеров ключевых носителей в рамках времени жизни разделяемой библиотеки "КриптоПро CSP 4.0". Для гарантированной инициализации ДСЧ с физического или БиоДСЧ, в случае если ранее могли не открываться контейнеры ключевых носителей, следует использовать функцию CPSetProvParam() с флагом PP_USE_HARDWARE_RNG.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCGenRandom .

См. также

CPSetProvParam() ,CPGenRandom в MS CSP World Wide Web link ,CryptGenRandom в MS CryptoAPI 2.0 World Wide Web link


CPGetKeyParam

Функция CPGetKeyParam() возвращает параметры ключа.

BOOL WINAPI CPGetKeyParam(
  HCRYPTPROV hProv,
  HCRYPTKEY hKey,
  DWORD dwParam,
  BYTE * pbData,
  DWORD * pdwDataLen,
  DWORD dwFlags
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
hKey
[in] Дескриптор ключа, параметры которого возвращаются.
dwParam
[in] Параметр, принимающий следующие возможные значения:
Значение dwParam | Содержимое буфера pbData
KP_ALGID | Идентификатор алгоритма (ALG_ID), соответствующий данному ключу.
KP_PERMISSIONS | Флаги разрешения использования ключа. Возвращаются в виде переменной типа DWORD.
KP_IV | Возвращает начальное значение вектора инициализации (IV или синхропосылки) алгоритма шифрования. Если ключ использовался в вызове CPEncrypt() или CPDecrypt() с параметром Final = FALSE, то значение данного параметра остается неизменным до вызова соответствующей функции с параметром Final = TRUE. По завершению работы функции начальное значение синхропосылки изменяется на случайное. До вызова CPEncrypt() или CPDecrypt() с параметром Final = FALSE значение параметра может быть изменено с помощью функции CPSetKeyParam().
KP_IV_BLOB | Возвращает начальное значение вектора инициализации (IV или синхропосылки) для алгоритма VKO GOST R 34.10-2012-256.
KP_CERTIFICATE | Получение сертификата из контейнера (из носителя).
KP_MODE Режим алгоритма шифрования. Возвращается в виде переменной типа DWORD. Используются режимы шифрования:
  • CRYPT_MODE_ECB - блочный шифр простой замены ГОСТ 28147-89;
  • CRYPT_MODE_CNT - шифрование гаммированием ГОСТ 28147-89;
  • CRYPT_MODE_CFB - шифрование гаммированием с обратной связью ГОСТ 28147-89;
  • CRYPT_MODE_CBCRFC4357 - блочный шифр с обратной связью на базе ГОСТ 28147-89, согласно RFC 4357;
  • CRYPT_MODE_CBCSTRICT - блочный шифр с обратной связью на базе ГОСТ 28147-89, шифртекст блока всегда является IV для следующего. Рекомендуется для использования только для обеспечения совместимости с существующими продуктами.
KP_MODE_BITS | Глубина обратной связи. Возвращается в виде переменной типа DWORD. Значение этой величины равно 64, что соответствует режиму гаммирования с обратной связью ГОСТ 28147-89.
KP_MIXMODE Режим преобразования ключа. Возвращается в виде переменной типа DWORD. Используются режимы преобразования:
  • CRYPT_PROMIX_MODE - преобразование после зашифрования каждых 1024 байт информации,
  • CRYPT_SIMPLEMIX_MODE - без преобразования.
KP_KEYLEN | Длина ключа в битах. Возвращается в виде переменной типа DWORD. Для ключей шифрования в параметре pbData возвращается длина ключа, для ключевых пар возвращается длина открытого ключа.
KP_BLOCKLEN | Длина блока шифрования, обрабатываемого криптопровайдером. Возвращается в виде переменной типа DWORD. В случае сессионного ключа если для ключа установлен режим блочного шифрованя (CRYPT_MODE_ЕСB, CRYPT_MODE_CBС), в параметре pbData устанавливается размер блока алгоритма ГОСТ 28147-89, если установлен режим поточного шифрования (CRYPT_MODE_CNT, CRYPT_MODE_CFB), в параметре pbData устанавливается значение оптимального с точки зрения скорости шифрования размера блока, принимаемого от приложения (в настоящее время 8Кбит). В случае ключевой пары в параметре pbData устанавливается число бит модуля q для ключей на базе эллиптической кривой (ГОСТ Р 34.10-2001 и ГОСТ Р 34.10-2012).
KP_CIPHEROID | Идентификатор узла замены, устанавливаемого приложением. Строковая величина с признаком конца строки.
KP_DHOID | Идентификатор алгоритма Диффи-Хеллмана. Строка, заканчивающаяся нулем.
KP_SIGNATUREOID | Идентификатор алгоритма подписи. Строка, заканчивающаяся нулем.
KP_HASHOID | Идентификатор функции хэширования, устанавливаемой приложением. Строка, заканчивающаяся нулем.
KP_DELTA | Возвращает значение дельты после установки на пользовательский ключ значение синхропосылки. Данные возвращаются в форме BLOB структуры, где pbData указавает на данные – 32 бита дельты, а cbData передаёт длину данных. Специфика протокола ООО "КРИПТО-ПРО" взаимодействия с функциональным ключевым носителем.
KP_FP | Возвращает первые 8 байт открытого ключа.
KP_NOTAFTER | См. Сроки действия долговременных ключей в "КриптоПро CSP 4.0" .
KP_UEC_DERIVE_COUNTER | Для ключа типа AT_UECSYMMETRICKEY возвращает значение счетчика ключей, полученных диверсификацией данного. Возвращается в виде переменной типа DWORD.
pbData
[out] Указатель на буфер данных параметра. Функция копирует соответствующие параметру данные в буфер. Формат этих данных зависит от значения dwParam. Если параметр - NULL, то данные не копируются. Требуемый размер буфера в байтах возвращается в pdwDataLen. Подробнее см. Возвращение данных неопределенной длины.
pdwDataLen
[in/out] Указатель на буфер, содержащий длину данных параметра. При вызове функции указанный параметр содержит число байтов в буфере pbData. После её выполнения параметр будет установлен числом байтов данных параметра, скопированных в буфер pbData. Если буфер, соответствующий pbData, недостаточно велик, чтобы в него копировать запрошенные данные, через функцию GetLastError() будет возвращён код ошибки ERROR_MORE_DATA. В этом случае требуемый размер буфера возвращается в pdwDataLen. Если эта функция завершается с кодом ошибки, отличным от ERROR_MORE_DATA, в этом параметре возвращается ноль.
dwFlags
[in] Значения флагов. Параметр зарезервирован для будущего использования и должен быть нулевым.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
ERROR_MORE_DATA | Размер буфера pbData недостаточен для копирования затребованных данных.
NTE_BAD_FLAGS | Параметр dwFlags имеет ненулевое значение.
NTE_BAD_TYPE | Параметр dwParam передаёт неизвестное значение параметра.
NTE_BAD_KEY | Дескриптор ключа ошибочен.
NTE_PERM | Попытка чтения ключевых параметров, когда право чтения криптопровайдером не представлено.
SCARD_E_NO_SUCH_CERTIFICATE | При попытке получения сертификата, когда сертификат отсутствует.

Примечания

Синхропосылка ключа для шифрования по алгоритму ГОСТ 28147-89 вырабатывается криптопровайдером автоматически с установкой типа ключа CALG28147 (сессионный ключ). Эту синхропосылку рекомендуется получить на передающем конце из ключа с помощью функции CPGetKeyParam() для значения pvParam KP_IV. На приёмном конце значение синхропосылки устанавливается на ключ функцией CPSetKeyParam() при значении pvParam KP_IV. Если требуется задание синхропосылки из приложения, то её рекомендуется вырабатывать с помощью функции CPGenRandom(). Использовать в системе другие алгоритмы образования синхропосылок можно только по согласованию с разработчиком криптопровайдера.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCGetKeyParam .

См. также

CPSetKeyParam() ,CPGetKeyParam в MS CSP World Wide Web link ,CryptGetKeyParam в MS CryptoAPI 2.0 World Wide Web link


CPGetUserKey

Функция CPGetUserKey() возвращает дескриптор одной из долговременных ключевых пар в ключевом контейнере.

BOOL WINAPI CPGetUserKey(
  HCRYPTPROV hProv,
  DWORD dwKeySpec,
  HCRYPTKEY * phUserKey
);

Аргументы

hProv
[in] Дескриптор криптопровайдера.
Получается при помощи функции CPAcquireContext().
dwKeySpec
[in] Спецификация возвращаемого ключа. Следующие типы ключевых пар и ключей определены в настоящее время:
Значение | Описание
AT_KEYEXCHANGE | Ключевая пара обмена
AT_SIGNATURE | Ключевая пара цифровой подписи
AT_UECSYMMETRICKEY | Симметричный ключ - мастерключ для систем аутентификации карт
phUserKey
[out] Адрес, по которому функция копирует дескриптор ключа.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_NO_KEY | Ключ, указанный dwKeySpec параметром, не существует.
NTE_BAD_TYPE | Значение параметра dwKeySpec неизвестно.
SCARD_W_CANCELLED_BY_USER | Пользователь прервал операцию нажатием клавиши Cancel
SCARD_W_WRONG_CHV | Пользователь ввёл неправильный пароль или пароль, установленный функцией SetProvParam(), неправильный
SCARD_E_INVALID_CHV | Пользователь ввёл пароль с нарушением формата или пароль, установленный функцией SetProvParam(), имеет неправильный формат. Например, пароль имеет недопустимую длину или содержит недопустимые символы.
SCARD_W_CHV_BLOCKED | Ввод Pin-кода был заблокирован смарт-картой, т.к. исчерпалось количество попыток разрешенное картой для ввода.
NTE_SILENT_CONTEXT | Операция не может быть выполнена без пользовательского интерфейса.
SCARD_W_REMOVED_CARD | Носитель контейнера был удален из считывателя

Примечания

При перечислении ключей типа AT_UECSYMMETRICKEY производится считывание ключа из ключевого контейнера. В некоторых случаях это может приводить к вызову окна запроса пароля ключа.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCGetUserKey .

См. также

CPExportKey() ,CPGenKey() ,CPGetUserKey в MS CSP World Wide Web link ,CryptGetUserKey в MS CryptoAPI 2.0 World Wide Web link


CPImportKey

Функция CPImportKey() используется для импорта криптографического ключа из ключевого блоба в контейнер криптопровайдера, для диверсификации ключа с использованием данных, передаваемых через ключевой блоб в соответствии с RFC 4357, п. 7., а так же для диверсификации ключа в соответствии с алгоритмами, описанным в п. 4.4, 4.5 рекомендаций по стандартизации "Криптографические алгоритмы, сопутствующие применению алгоритмов электронной цифровой подписи и функции хэширования".

BOOL WINAPI CPImportKey(
  HCRYPTPROV hProv,
  CONST BYTE * pbData,
  DWORD dwDataLen,
  HCRYPTKEY hImpKey,
  DWORD dwFlags,
  HCRYPTKEY * phKey
);

Аргументы

pbData
[in] Указатель на буфер, содержащий ключевой блоб, произведенный с иcпользованием функции CPExportKey() данным или другим криптопровайдером, функционирующим на удалённом компьютере, или блоб диверсификации, используемый для диверсификации ключа на основе данных, передаваемых через блоб в соответствии с RFC 4357, п. 7. или в соответствии с п. 4.4, 4.5 рекомендаций по стандартизации "Криптографические алгоритмы, сопутствующие применению алгоритмов электронной цифровой подписи и функции хэширования"
dwDataLen
[in] Длина ключевого блоба в байтах.
hImpKey
[in] Дескриптор ключа, на котором осуществляется снятие криптографической защиты импортируемого ключа. Значение этого параметра должно соответствовать значению hExpKey, определённому для функции CPExportKey() при создании ключевого блоба. После зашифрования ключевого блоба на сессионном ключе этот параметр содержит дескриптор на сессионный ключ. Если ключевой блоб не зашифрован (например, PUBLICKEYBLOB), этот параметр не используется и должен быть равен нулю. В алгоритме диверсификации hImpKey - исходный ключ, из которого вырабатываются диверсифицированные ключи.
dwFlags
[in] Значение флага. Этот параметр в настоящее время используется только, когда ключевая пара (закрытый/открытый ключи) импортируется в криптопровайдер (в форме PRIVATEKEYBLOB). Если импортируемый ключ будет заново экспортироваться, в этот параметр помещается флаг CRYPT_EXPORTABLE. Если этот флаг не используется, вызовы функции CryptExportKey в MS CryptoAPI 2.0 World Wide Web link с дескриптором ключа будут терпеть неудачу.
phKey
[out] Адрес, по которому функция копирует дескриптор импортированного либо диверсифицированного ключа. В алгоритме диверсификации ключ phKey наследует параметры ключа hImpKey: KP_OID, KP_MODE, KP_MIXMODE, KP_PADDING. При импорте ключей CALG_GR3410EL, CALG_DH_EL_SF, CALG_DH_GR3410_12_256_SF, CALG_GR3410_12_256, CALG_DH_GR3410_12_512_SF, CALG_GR3410_12_512, CALG_UECSYMMETRIC, если ключевой контейнер не содержит соответствующих ключей AT_SIGNATURE, AT_KEYEXCHANGE, AT_UECSYMMETRICKEY, импортируемые ключи устанавливаются в ключевой контейнер

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError.
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_DATA | Не прошёл контроль целостности импортируемого ключевого блоба. Ошибочная длина блоба.
NTE_BAD_FLAGS | Параметр dwFlags содержит ошибочную величину.
NTE_BAD_KEY | Один или оба из ключей, указанных hKey и hImpKey, не действительны. Байты в элементах заголовка ключевого блоба типа WORD, DWORD имеют обратный порядок по отношению к данной платформе.
NTE_BAD_TYPE | Тип ключевого блоба не поддерживается этим криптопровайдером и, возможно, ошибочен.
NTE_PERM | Попытка импорта ключа, когда право импорта криптопровайдером не предоставлено.
NTE_NO_MEMORY | Криптопровайдер во время операции исчерпал память.
NTE_FAIL | Нарушение целостности ключей в ОЗУ. см. Дополнительные параметры и определения .
SCARD_W_CANCELLED_BY_USER | Пользователь прервал операцию нажатием клавиши Cancel
SCARD_W_WRONG_CHV | Пользователь ввёл неправильный пароль или пароль, установленный функцией SetProvParam(), неправильный
SCARD_E_INVALID_CHV | Пользователь ввёл пароль с нарушением формата или пароль, установленный функцией SetProvParam(), имеет неправильный формат. Например, пароль имеет недопустимую длину или содержит недопустимые символы.
SCARD_W_CHV_BLOCKED | Ввод Pin-кода был заблокирован смарт-картой, т.к. исчерпалось количество попыток, разрешенное картой для ввода.
NTE_TOKEN_KEYSET_STORAGE_FULL | Недостаточно места на носителе для сохранения информации.
NTE_SILENT_CONTEXT | Операция не может быть выполнена без пользовательского интерфейса.
SCARD_W_REMOVED_CARD | Носитель контейнера был удалён из считывателя
NTE_EXISTS | Попытка импортировать ключ в случае, когда ключ соответствующего типа в контейнере существует.

Примечания

Обычно для согласования (экспорта/импорта) сессионного ключа применяют алгоритм Диффи-Хеллмана. В этом случае ключ парной связи (ключ экспорта/импорта сессионного ключа) порождается операцией импорта открытого ключа получателя (отправителя) на ключевой паре отправителя (получателя). Следует учитывать, что при использовании эфемерных ключей аутентификация пользователей не обеспечивается. Для импорта сессионного ключа следует выполнить следующие шаги:

  • Импорт блоба открытого ключа отправителя (CRYPT_PUBLICKEYBLOB ) на своей ключевой паре;
  • Импорт сессионого ключа (CRYPT_SIMPLEBLOB ) на ключе парной связи.

      ...
      CPGetUserKey(hProv, AT_KEYEXCHANGE, &hUserKey);
      ...
      CPImportKey(hProv, pbSenderPublicKey, cbSenderPublicKey, hUserKey, 0, &hExchKey);
      ALG_ID ke_alg = CALG_PRO_EXPORT;
      CPSetKeyParam(hProv, hExchKey, KP_ALGID, (LPBYTE)&ke_alg, 0);
      CPImportKey(hProv, pbSessionKeyFromSender, &cbSessionKeyFromSender, hExchKey, 0, &hSessionKey);
      ...

Для ключей 2012 в качестве алгоритма согласования сессионного ключа используется алгоритм VKO GOST R 34.10-2012-256 (на основе функции хэширования ГОСТ Р 34.11-2012-256), параметр KP_CIPHEROID результирующего ключа принимает значение, установленное в параметрах импортируемого открытого ключа (если не указано, то "1.2.643.7.1.2.5.1.1", вариант ТК26 Z). Режимы шифрования, преобразования ключа и дополнения открытого текста до кратности блока для получаемого ключа устанавливаются аналогично вновь создаваемому ключу (см. CPSetKeyParam()).

Для ключей 2001 используется алгоритм VKO GOST R 34.10-2001 (на основе функции хэширования ГОСТ Р 34.11-94). При использовании данного алгоритма с долговременным ключом параметр KP_CIPHEROID полученного ключа принимает oid параметров шифрования, установленный в соответствующем долговременному ключу контейнере; при использовании с эфемерным ключом параметр KP_CIPHEROID результирующего ключа принимает установленное для провайдера значение PP_CIPHEROID. Режимы шифрования, преобразования ключа и дополнения открытого текста до кратности блока для получаемого ключа устанавливаются аналогично вновь создаваемому ключу (см. CPSetKeyParam()).

В случае импорта SIMPLEBLOB набор узлов замены устанавливается в соответствии с указанным в блобе. Режимы шифрования, преобразования ключа и дополнения открытого текста до кратности блока для получаемого ключа устанавливаются аналогично вновь создаваемому ключу (см. CPSetKeyParam()).

В случае импорта OPAQUEKEYBLOB набор узлов замены, режимы шифрования, преобразования ключа и дополнения открытого текста до кратности блока устанавливаются в соответствии с параметрами, указанными в блобе.

С помощью этой же функции в режиме диверсификации ключа (CRYPT_DIVERSBLOB ) можно создавать ключи блоков (пакетов) на основе сессионного ключа.

      // Пример получения ключа блока (пакета) на основе ключа сесcии (файла, ассоциации)
      // с помощью возможности диверсификации ключа функцией CPImportKey в соответствии с
      // алгоритмом, описанным в п.7 RFC 4357.
      // bBlockNumber - байтовая последовательность, диверсифицирующая ключ.
      Blob.DiversBlobHeader.BlobHeader.bType = DIVERSKEYBLOB;
      Blob.DiversBlobHeader.BlobHeader.bVersion = 0x20;
      Blob.DiversBlobHeader.BlobHeader.reserverd = 0;
      Blob.DiversBlobHeader.BlobHeader.aiKeyAlg = CALG_G28147;
      Blob.DiversBlobHeader.aiDiversAlgId = CALG_PRO_DIVERS;
      Blob.DiversBlobHeader.dwDiversMagic = 0x31564944;
      Blob.DiversBlobHeader.cbDiversData = sizeof(bBlockNumber);
      CopyMemory((LPBYTE)Blob.bDiversData,bBlockNumber,sizeof(bBlockNumber));
      CPImportKey(hCSP, hProv, &Blob, sizeof(Blob), hSessionKey, 0, &hBlkKey);
      // Диверсификация в соответствии с алгоритмом KDF_GOSTR3411_2012_256
      // проводится аналогично с тем отличием, что в поле aiDiversAlgId
      // записывается константа CALG_PRO12_DIVERS
      ...

С помощью этой же функции в режиме диверсификации ключа (CRYPT_KDF_TREE_DIVERSBLOB ) можно создавать ключи блоков (пакетов) на основе процедуры диверсификации КриптоПро CSP, предусматривающей возможность выработки нескольких ключей.

      ...
      // Пример выработки нескольких ключей на основе ключа диверсификации
      // с помощью алгоритма CALG_KDF_TREE_GOSTR3411_2012_256, описанного
      // в п.4.5 рекомендаций по стандартизации "Криптографические алгоритмы,
      // сопутствующие применению алгоритмов электронной цифровой подписи и функции хэширования"
      // bSeedData - байтовая последовательность Seed, диверсифицирующая ключ.
      // bLabelData - байтовая последовательность Label, диверсифицирующая ключ.
      dwBlobLen = sizeof(CRYPT_KDF_TREE_DIVERSBLOB_HEADER) + sizeof(CRYPT_KDF_TREE_DIVERS_INFO) +
          sizeof(bSeedData) + sizeof(bLabelData);
      DiversBlob.KdfTreeBlobHeader.BlobHeader.aiKeyAlg = CALG_G28147;
      DiversBlob.KdfTreeBlobHeader.BlobHeader.bType = KDF_TREE_DIVERSBLOB;
      DiversBlob.KdfTreeBlobHeader.BlobHeader.bVersion = BLOB_VERSION;
      DiversBlob.KdfTreeBlobHeader.BlobHeader.reserved = 0;
      DiversBlob.KdfTreeBlobHeader.aiDiversAlgId = CALG_KDF_TREE_GOSTR3411_2012_256;
      DiversBlob.KdfTreeBlobHeader.dwIterNum = 1;
      DiversBlob.KdfTreeDiversInfo.dwLabelLen = sizeof(bLabelData);
      DiversBlob.KdfTreeDiversInfo.dwSeedLen = sizeof(bSeedData);
      DiversBlob.KdfTreeDiversInfo.L_value = 1024;
      DiversBlob.KdfTreeDiversInfo.R_value = 2;
      CopyMemory((LPBYTE)DiversBlob.bDiversData, bSeedData, sizeof(bSeedData));
      CopyMemory((LPBYTE)DiversBlob.bDiversData + sizeof(bSeedData), bLabelData, sizeof(bLabelData));
      // Первичный вызов с передачей всех параметров диверсификации
      CPImportKey(hCSP, hProv, &DiversBlob, dwBlobLen, hSessionKey, 0, &hDivKey[0]);
      // Для последующих вызовов достаточно передачи хэдера с нужным номером ключа
      // Вызовы с различными номерами результирующих ключей могут идти не по порядку
      DiversBlob.KdfTreeBlobHeader.dwIterNum = 3;
      CPImportKey(hCSP, hProv, &DiversBlob.KdfTreeBlobHeader,
          sizeof(CRYPT_KDF_TREE_DIVERSBLOB_HEADER), hSessionKey, 0, &hDivKey[1]);
      ...

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCImportKey .

См. также

CRYPT_PRIVATEKEYBLOB ,CRYPT_PUBLICKEYBLOB ,CRYPT_SIMPLELOB ,CRYPT_DIVERSBLOB ,CPExportKey() ,CPGenKey() ,CPImportKey в MS CSP World Wide Web link ,CryptImportKey в MS CryptoAPI 2.0 World Wide Web link


CPSetKeyParam

Функция CPSetKeyParam() устанавливает параметры ключа.

BOOL WINAPI CPSetKeyParam(
  HCRYPTPROV hProv,
  HCRYPTKEY hKey,
  DWORD dwParam,
  BYTE * pbData,
  DWORD dwFlags
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
hKey
[in] Дескриптор ключа, параметры которого устанавливаются.
dwParam
[in] Параметр, принимающий следующие возможные значения:
Значение dwParam | Содержимое буфера pbData
KP_ALGID Идентификатор алгоритма ключа (ALG_ID), соответствующий данному ключу. Передаётся функции через буфер pbData. Возможо установить значение CALG_G28147 для ключей класса ALG_CLASS_DATA_ENCRYPT (сессионных ключей).
ALG_ID | Описание
CALG_G28147 | Ключ шифрования и/или имитозащиты данных по ГОСТ 28147-89. В последствии этот ключ можно пометить как ключ для импорта/экспорта с помощью функции CPSetKeyParam().
CALG_SYMMETRIC_512 | Ключ парной связи по Диффи-Хеллману с длиной выхода 512 бит.
CALG_PRO_EXPORT | Ключ экспорта/импорта ключей типа CALG_G28147 для хранения на диске или передачи по каналу связи.
CALG_PRO12_EXPORT | Ключ защищённого экспорта по рекомендациям ТК26 (обязателен для использования с ключами ГОСТ Р 34.10-2012).
CALG_SIMPLE_EXPORT Ключ экспорта/импорта ключей типа CALG_G28147 по ГОСТ 28147-89 в режиме простой замены для хранения на ключевом носителе.

Использование CALG_SIMPLE_EXPORT для ключей CALG_G28147, переданных в канале связи, возможно только в случае обеспечения строгой однократности операции импорта ключа принимающей стороной и гарантированной случайности получения ключа передающей стороной.

Использование CALG_SIMPLE_EXPORT при экспорте/импорте ключей CALG_TLS1_MASTER происходит с усложнением ключа аналогичным CALG_PRO_EXPORT.

Недопустимо использование CALG_SIMPLE_EXPORT для экспорта/импорта ключей с целью их хранения на диске.
CALG_TLS1_MASTER | Ключ для реализации протокола TLS.
CALG_TLS1_MAC_KEY | Ключ для реализации протокола TLS.
CALG_TLS1_ENC_KEY | Ключ для реализации протокола TLS.
Устанавливает значения CALG_EKE_CIPHER на ключ CALG_PRO_AGREEDKEY_DH. Так же на ключ CALG_EKE_CIPHER может быть установлен тип CALG_PRO_AGREEDKEY_DH. Специфика протокола ООО "КРИПТО-ПРО" взаимодействия с функциональным ключевым носителем.
KP_IV | Устанавливает начальное значение вектора инициализации (IV или синхропосылки) алгоритма шифрования. Начальное значение синхропосылки по умолчанию (после создания, дублирования и или завершения операции шифрования) - случайное. Последовательность байтов, содержащая IV, передаётся функции через буфер pbData. Если ключ использовался в вызове CPEncrypt() или CPDecrypt() с параметром Final = FALSE, то изменение данного параметра невозможно до вызова соответствующей функции с параметром Final = TRUE.
KP_IV_BLOB | Устанавливает начальное значение вектора инициализации (IV или синхропосылки) для алгоритма VKO GOST R 34.10-2012-256. Начальное значение синхропосылки по умолчанию - случайное. Данные передаются в форме BLOB структуры, где член структуры pbData указывает на данные, а cbData передаёт длину данных.
KP_CERTIFICATE | Установка сертификата в контейнер (на носитель). Сертификат должен соответствовать ключу в контейнере.
KP_PADDING Способ дополнения. Величина DWORD, содержащая метод дополнения, используемый шифром ключа, передаётся функции через буфер pbData. В настоящее время определены следующие способы дополнения:
  • PKCS5_PADDING - PKCS#5.(См ПРИМЕЧАНИЕ в данном разделе и ПРИМЕЧАНИЕ к CryptSetKeyParam в MS CryptoAPI 2.0 World Wide Web link )
  • ZERO_PADDING - дополнение нулевыми байтами,
  • RANDOM_PADDING - дополнение случайными байтами,
  • ISO10126_PADDING - дополнение в соответствии с ISO 10126,
  • ANSI_X923_PADDING - дополнение в соответствии с ANSI X.923.
При первоначальной выработке ключа по умолчанию устанавливается значение PKCS5_PADDING.
KP_MODE

Режим шифра. Переменная типа DWORD. Передаётся функции через буфер pbData. Если ключ использовался в вызове CPEncrypt() или CPDecrypt() с параметром Final = FALSE, то изменение данного параметра невозможно до вызова соответствующей функции с параметром Final = TRUE. В следующем списке приведены режимы шифрования для ключей CALG_G28147 класса ALG_CLASS_DATA_ENCRYPT, доступные в настоящее время:

  • CRYPT_MODE_ECB - блочный шифр простой замены ГОСТ 28147-89;
  • CRYPT_MODE_CNT - шифрование гаммированием ГОСТ 28147-89;
  • CRYPT_MODE_CFB - шифрование гаммированием с обратной связью ГОСТ 28147-89;
  • CRYPT_MODE_CBCRFC4357 - блочный шифр с обратной связью на базе ГОСТ 28147-89, согласно RFC 4357;
  • CRYPT_MODE_CBCSTRICT - блочный шифр с обратной связью на базе ГОСТ 28147-89, шифртекст блока всегда является IV для следующего. Рекомендуется для использования только для обеспечения совместимости с существующими продуктами.
При первоначальной выработке ключа по умолчанию устанавливается значение CRYPT_MODE_CFB.

Для ключей CALG_EKE_CIPHER доступны режимы шифрования:

  • CRYPT_MODE_EKEXOR - одноразовый шифр гаммирования по модулю 2, в данном режиме вычисляется значение открытого ключа, соответсвующего ключу CALG_PRO_AGREEDKEY_DH и координата X ключа накладывается по модулю 2 на данные, данные длиной 32 байта должны подаваться одним блоком;
  • CRYPT_MODE_EKEECADD - одноразовый шифр гаммирования в группе точек эллиптической кривой, в данном режиме вычисляется значение открытого ключа, соответсвующего ключу CALG_PRO_AGREEDKEY_DH и ключ накладывается на данные аддитивно в группе точек эллиптической кривой, данные должны быть блобом открытого ключа длиной 100 байт и подаваться одним блоком.

KP_MODE_BITS | Глубина обратной связи. Переменная типа DWORD. Значение этой величины равно 64, что соответствует режиму гаммирования с обратной связью ГОСТ 28147-89.
KP_MIXMODE | Дополнительный параметр ключа. Устанавливает режим преобразования ключа после зашифрования каждых 1024 байт информации. Режим преобразования ключа (CRYPT_PROMIX_MODE) установлен по умолчанию. Выйти из этого режима можно, если для этого параметра в pbData будет установлено CRYPT_SIMPLEMIX_MODE. Если в pbData установлено CRYPT_PROMIX_MODE, устанавливается режим преобразования ключа. Размер pbData - 4 байта. Может быть установлен для ключей типа CALG_G28147. Если ключ использовался в вызове CPEncrypt() или CPDecrypt() с параметром Final = FALSE, то изменение данного параметра невозможно до вызова соответствующей функции с параметром Final = TRUE.
KP_MIXSTART | Осуществляет диверсификацию ключа по алгоритму CALG_PRO_DIVERS. Через параметр pbData передаётся блоб диверсификации ключа в форме CRYPT_DATA_BLOB, см. CPCImportKey(). Допускается многократный вызов с различными параметрами диверсификации.
KP_CIPHEROID | Идентификатор узла замены. Строка, заканчивающаяся нулем. При первоначальной выработке ключа по умолчанию устанавливается в соответствии с параметрами, указанными в панели криптопровайдера. Для провайдера PROV_GOST_2001_DH в панели по умолчанию указан набор "ГОСТ 28147-89, параметры по умолчанию" (szOID_Gost28147_89_CryptoPro_A_ParamSet, 1.2.643.2.2.31.1), для PROV_GOST_2012_256 и PROV_GOST_2012_512 - набор "ГОСТ 28147-89, параметры шифрования ТК 26 Z" (szOID_Gost28147_89_TC26_Z_ParamSet, 1.2.643.7.1.2.5.1.1).
KP_DHOID | Идентификатор параметров ключа ГОСТ Р 34.10-2001, применяемых в алгоритме Диффи-Хеллмана. Строка, заканчивающаяся нулем. Начиная с версии 3.6 допускается устанавливать идентификаторы подписи. Необходимо устанавливать глобальным параметром PP_DHOID до генерации ключа.
KP_HASHOID | Идентификатор функции хэширования. Строка, заканчивающаяся нулем. Необходимо устанавливать глобальным параметром PP_HASHOID до генерации ключа.
KP_CLIENT_RANDOM | Идентификатор величины ClientRandom, используемой с ключами типа CALG_TLS1_MASTER. Размер ClientRandom - 32 байта. Используется при преобразовании premaster_secret в master_secret и при генерации ключевой информации в момент создания хэша CALG_TLS1_MASTER_HASH.
KP_SERVER_RANDOM | Идентификатор величины ServerRandom, используемой с ключами типа CALG_TLS1_MASTER.Размер ServerRandom - 32 байта. Используется при преобразовании premaster_secret в master_secret и при генерации ключевой информации в момент создания хэша CALG_TLS1_MASTER_HASH.
KP_PREHASH

Идентификатор, используемый ключами типа CALG_TLS1_MASTER. Предварительно требуется установить KP_CLIENT_RANDOM и KP_SERVER_RANDOM. Вызов функции преобразует premaster_secret в master_secret.

KP_X | Закрытый ключ в ключевой паре. 32 байта для ключей ГОСТ Р 34.10-2012 длины 256 бит (ГОСТ Р 34.10-2001) и 64 байта для ключей ГОСТ Р 34.10-2012 длины 512 бит в форме little endian. Данные передаются в форме BLOB структуры, где член структуры pbData указавает на данные, а cbData передаёт длину данных.
KP_MULX | Для произвольной ключевой пары осуществляет умножение закрытого и открытого ключей на значение передаваемого параметра pbData. Для ключа CALG_PRO_AGREEDKEY_DH осуществляет умножение закрытого ключа на значение передаваемого параметра pbData. Данные передаются в форме BLOB структуры, где член структуры pbData указавает на данные - 32 байта для ключей ГОСТ Р 34.10-2012 длины 256 бит (ГОСТ Р 34.10-2001) и 64 байта для ключей ГОСТ Р 34.10-2012 длины 512 бит в форме little endian, а cbData передаёт длину данных.
KP_MULX_INVERS | Аналогично KP_MULX осуществляет умножение на величину, обратную к величине, передаваемой в параметре pbData.
KP_ADDX | Для закрытого ключа осуществляет сложение по модулю q значения ключа и значения смещения, передаваемого через параметр pbData. Данные передаются в форме BLOB структуры, где поле pbData указавает на данные - смещение, а cbData передаёт длину данных.
KP_SUBX | Для открытого ключа осуществляет вычитание по модулю q из значения ключа значения смещения, передаваемого через параметр pbData. Данные передаются в форме BLOB структуры, где поле pbData указывает на данные - смещение, а cbData передаёт длину данных.
KP_ECADD | Для открытого ключа осуществляет сложение в группе точек эллиптической кривойо ткрытого ключа и значения блоба открытого ключа, передаваемого через параметр pbData. Данные передаются в форме BLOB структуры, где поле pbData указавает на данные - блоб открытого ключа, а cbData передаёт длину данных.
KP_ECSUB | Для открытого ключа осуществляет вычитание в группе точек эллиптической кривой открытого из ключа значение блоба открытого ключа, передаваемого через параметр pbData. Данные передаются в форме BLOB структуры, где поле pbData указавает на данные - блоб открытого ключа, а cbData передаёт длину данных.
KP_DEMASKPUBLIC | Устанавливает открытый ключ на ключ CALG_PRO_AGREEDKEY_DH, что обеспечивает расшифрование ключа в алгоритме выработки ключа обмена с использованием функционального ключевого носителя. Специфика протокола ООО "КРИПТО-ПРО" взаимодействия с функциональным ключевым носителем.
KP_SYNCRO | Устанавливает значение синхропосылки на ключ пользователя. Ключ должен быть создан в контексте с флагом CRYPT_TOKEN_SHARED. Данные передаются в форме BLOB структуры, где pbData указавает на данные – 32 бита синхропосылки, а cbData передаёт длину данных. Специфика протокола ООО "КРИПТО-ПРО" взаимодействия с функциональным ключевым носителем.
KP_UEC_DERIVE_COUNTER | Для ключа типа AT_UECSYMMETRICKEY устанавливает значение счетчика ключей, полученных диверсификацией данного. Переменная типа DWORD.
pbData
[in] Указатель на буфер данных параметра. При вызове функции буфер содержит, соответствующие значению параметра в dwParam. Формат данных зависит от типа параметра.
dwFlags
[in] Значения флагов. Параметр зарезервирован для будущего использования и должен быть нулевым.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError.
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_FLAGS | Параметр dwFlags имеет ненулевое значение.
NTE_BAD_TYPE | Параметр dwParam передаёт неизвестное значение параметра.
NTE_BAD_KEY | Дескриптор ключа ошибочен.
NTE_BAD_KEY_STATE | Указанный параметр временно не может быть изменен.
NTE_PERM | Попытка чтения ключевых параметров, когда право чтения криптопровайдером не предоставлено.
NTE_FIXEDPARAMETER | Была произведена попытка установить параметры, постоянные для данного криптопровайдера.
NTE_BAD_DATA | Неправильные данные в буфере pbData.

Примечания

ДОПОЛНЕНИЕ PKCS #5 Эта схема дополнения определена RSA Data Security, Inc. и описана в "Public-Key Cryptography Standards (PKCS)", PKCS #5, раздел 6.2. При использовании данной схемы последовательность всегда дополняется знаками, даже в случае, когда её длина кратна длине блока шифрования. Последовательность дополнения состоит из байтов, каждый из которых равен числу дополнительных байтов. Если дополняется последовательность из 24 бит, последовательность дополнения равна “05 05 05 05 05”. Если дополняется 64 бита, последовательность дополнения равна “08 08 08 08 08 08 08 08”. При расшифровании, если расширение блока удовлетворяет условиям дополнения PKCS #5, функция CPDecrypt() в переменной pdwDataLen, возвращает истинное значение длины открытого текста. Если расширение блока не удовлетворяет условиям дополнения PKCS #5, функция CPDecrypt() возвращает ошибку NTE_BAD_DATA, а в переменной pdwDataLen значение длины шифрованного текста. ДОПОЛНЕНИЕ ZERO При использовании данной схемы, последовательность дополняется нулевыми байтами до наименьшей длины, кратной длине блока шифрования. ДОПОЛНЕНИЕ RANDOM При использовании данной схемы, последовательность дополняется случайными байтами до наименьшей длины, кратной длине блока шифрования. ДОПОЛНЕНИЕ ISO 10126 Эта схема определена стандартом ISO 10126. При использовании данной схемы последовательность всегда дополняется знаками, даже если её длина кратна длине блока шифрования. Последовательность дополнения кроме последнего байта состоит из случайных байтов, в последнем байте указывается общая длина дополнения в байтах. Если дополняется последовательность длиной 24 бита, то последовательность дополнения может быть следующей: "6F 43 3D B2 05", где первые 4 байта выбраны случайно. Если дополняются 64 бита, последовательность дополнения может быть следующей: "B6 87 2D 4A 40 A1 F9 08", где первые семь байт выбраны случайно. При расшифровании, если расширение блока удовлетворяет условиям дополнения ISO 10126, функция CPCDecrypt() в переменной pdwDataLen, возвращает истинное значение длины открытого текста. Если расширение блока не удовлетворяет условиям дополнения ISO 10126, функция CPCDecrypt() возвращает ошибку NTE_BAD_DATA, а в переменной pdwDataLen значение длины шифрованного текста. ДОПОЛНЕНИЕ ANSI X.923 Эта схема определена стандартом ANSI X.923. При использовании данной схемы последовательность всегда дополняется знаками, даже если её длина кратна длине блока шифрования. Последовательность дополнения кроме последнего байта состоит из нулевых байтов, в последнем байте указывается общая длина дополнения в байтах. Если дополняется последовательность длиной 24 бита, то последовательность дополнения является следующей: "00 00 00 00 05". Если дополняются 64 бита, последовательность дополнения является следующей: "00 00 00 00 00 00 00 08". При расшифровании, если расширение блока удовлетворяет условиям дополнения ANSI X.923, функция CPCDecrypt() в переменной pdwDataLen, возвращает истинное значение длины открытого текста. Если расширение блока не удовлетворяет условиям дополнения ANSI X.923, функция CPCDecrypt() возвращает ошибку NTE_BAD_DATA, а в переменной pdwDataLen значение длины шифрованного текста.

РЕЖИМ CRYPT_MODE_ECB В соответствии с требованиями ГОСТ 28147-89 режим шифрования простой заменой CRYPT_MODE_ECB может использоваться только для шифрования ключевой информации.

Значение параметра KP_CIPHEROID, установленное на долговременный ключ, сохраняется только в текущем контексте. После вызова функции CPReleaseContext() при повторном открытии контейнера и обращении к ключу данный параметр примет установленное в контейнере значение.

Значения параметров KP_MODE, KP_MIXMODE, KP_CIPHEROID и KP_PADDING, устанавливаемые по умолчанию во вновь создаваемый симметричный ключ операциями CPImportKey(), CPDuplicateKey() и CPDeriveKey(), указаны в соответствующих разделах.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCSetKeyParam .

См. также

CPGenKey() ,CPGetKeyParam() ,CPSetKeyParam в MS CSP World Wide Web link ,CryptSetKeyParam в MS CryptoAPI 2.0 World Wide Web link


Функции шифрования/расшифрования данных

Функции шифрования/расшифрования данных предназначены для выполнения операций, шифрования и расшифрования данных.

Функции | Описание
CPEncrypt | Функция CPEncrypt() производит зашифрование данных. Одновременно может быть произведено их хэширование.
CPDecrypt | Функция CPDecrypt() расшифровывает данные, предварительно зашифрованные функцией CPEncrypt(). Одновременно может быть произведено хэширование данных.


CPEncrypt

Функция CPEncrypt() производит зашифрование данных. Одновременно может быть произведено их хэширование.

BOOL WINAPI CPEncrypt(
  HCRYPTPROV hProv,
  HCRYPTKEY hKey,
  HCRYPTHASH hHash,
  BOOL Final,
  DWORD dwFlags,
  BYTE * pbData,
  DWORD * pdwDataLen,
  DWORD dwBufLen
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
hKey
[in] Дескриптор ключа сессии, используемого для зашифрования данных.
hHash
[in] Дескриптор объекта функции хэширования. Если значение хэш-функции не вычисляется, этот параметр равен нулю.
Final
[in] Булева величина. Определяет, является ли переданный функции блок последним зашифрованным блоком данных. Она должна быть установлена TRUE, если это последний (или единственный) блок, и FALSE – в противном случае. При установке флага Final == TRUE, состояние усложнения ключа возвращается в первоначальное, а начальное значение синхропосылки устанавливается в случайное значение.
dwFlags
[in] Значения флагов. Параметр определяет способ обработки фрагмента данных в потоке. Нулевое значение соответствует шифрованию фрагмента данных потока, ненулевое значение соответствует обработке пакета данных. См. Шифрование и хэширование пакета .
pbData
[in/out] Если значение dwFlags нулевое, указатель на буфер, содержащий данные для зашифрования. Если установлен флаг CP_CRYPT_HASH_PACKET - указатель на буфер, содержащий пакет. См. Шифрование и хэширование пакета . Если установлены флаги CP_CRYPT_HASH_PACKET и CP_CRYPT_DATA_IOVEC, указатель на массив структур CSP_iovec, задающий пакет. См. Вектор ввода вывода . После шифрования данные помещаются в этот же буфер или передаются через массив структуру CSP_iovec. Если установлены флаги CP_CRYPT_HASH_PACKET и CP_CHP_MULTIPACKET, указатель на массив структур CSP_Multipacket_ENC, задающий массив пакетов для параллельной обработки на платформах, поддерживающих SIMD архитектуру SSE_x, SSSE_x, AVX. См. Мультипакетная обработка .
pdwDataLen
[in/out] Если значение dwFlags нулевое, указатель на буфер, содержащий длину данных. Параметр dwDataLen определяет число байтов открытого текста в буфере pbData. Через этот параметр функция возвращает указатель на число байтов шифртекста, помещённого в буфер pbData. Если установлен флаг CP_CRYPT_HASH_PACKET, указатель на буфер, содержащий длину пакета. Если установлены флаги CP_CRYPT_HASH_PACKET и CP_CHP_STARTMIX, по указателю pdwDataLen передаётся и возвращается длина пакета включая блоб диверсификации ключей. Если установлены флаги CP_CRYPT_HASH_PACKET,CP_CRYPT_DATA_IOVEC и CP_CHP_STARTMIX, по указателю pdwDataLen передаётся и возвращается общая длина элементов вектора включая блоб диверсификации ключей (в этом варианте использования, блоб диверсификации должен передаваться отдельным первым элементом). Если установлены флаги CP_CRYPT_HASH_PACKET и CP_CHP_MULTIPACKET, указатель на количество структур CSP_Multipacket_ENC.
dwBufLen
[in] Если значение dwFlags нулевое, размер буфера pbData в байтах при условии возможности помещения в буфер зашифрованных данных. Если установлен флаг CP_CRYPT_HASH_PACKET, размер буфера pbData в байтах. Если установлены флаги CP_CRYPT_HASH_PACKET и CP_CRYPT_DATA_IOVEC, число элементов массива CSP_iovec. Если установлены флаги CP_CRYPT_HASH_PACKET, CP_CHP_MULTIPACKET, данный параметр должен иметь нулевое значение.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_ALGID | Ключ hKey определяет алгоритм, который данный криптопровайдер не поддерживает.
NTE_BAD_FLAGS | Величина dwFlags имеет некорректное значение, например, ненулевое значение при неустановленном флаге CP_CRYPT_HASH_PACKET.
NTE_BAD_DATA | Данные для зашифрования недействительны. В частности, в блочных режимах шифрования, если Final = FALSE, а длина шифруемого текста не кратна длине блока шифрования, возвращается данная ошибка. При шифровании пакета - ошибка формирования пакета.
NTE_BAD_KEY | Ключ недействителен. В частности, эта ошибка возвращается, если на ключе в состоянии CRYPT_SIMPLEMIX_MODE зашифровано более 4-x мегабайт текста.
NTE_BAD_HASH | Дескриптор хэша ошибочен.
NTE_BAD_LEN | Размер буфера недостаточен для помещения в него шифртекста. Если установлены флаги CP_CRYPT_HASH_PACKET,CP_CRYPT_DATA_IOVEC - длина, передаваемая в dwDataLen не совпадает с суммой длин координат IOVEC.
NTE_PERM | Право зашифрования на данном ключе криптопровайдером не предоставлено.
NTE_FAIL | Нарушение целостности ключей в ОЗУ. см. Дополнительные параметры и определения .

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCEncrypt .

См. также

CPDecrypt() ,CPGenKey() ,CPEncrypt в MS CSP World Wide Web link ,CryptEncrypt в MS CryptoAPI 2.0 World Wide Web link


CPDecrypt

Функция CPDecrypt() расшифровывает данные, предварительно зашифрованные функцией CPEncrypt(). Одновременно может быть произведено хэширование данных.

BOOL WINAPI CPDecrypt(
  HCRYPTPROV hProv,
  HCRYPTKEY hKey,
  HCRYPTHASH hHash,
  BOOL Final,
  DWORD dwFlags,
  BYTE * pbData,
  DWORD * pdwDataLen
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
hKey
[in] Дескриптор сессионного ключа, используемого для расшифрования данных. Недопустимо использование одного ключа в многопоточной обработке. Для организации многопоточной обработки необходимо размножать ключ с использованием функции CPCDuplicateKey().
hHash
[in] Дескриптор объекта хэширования. Если хэширование данных одновременно с их расшифрованием не требуется, этот параметр должен быть нулевым.
Final
[in] Булева величина. Определяет, является ли переданный функции блок последним расшифрованным блоком данных. Она должна быть установлена TRUE, если блок - последний или единственный, и FALSE – в противном случае. При установке флага Final == TRUE, состояние усложнения ключа возвращается в первоначальное, а начальное значение синхропосылки устанавливается в случайное значение.
dwFlags
[in] Значения флагов. Параметр определяет способ обработки фрагмента данных в потоке. Нулевое значение соответствует шифрованию фрагмента данных потока, ненулевое значение соответствует обработке пакета данных. См. Шифрование и хэширование пакета .
pbData
[in/out] Если значение dwFlags нулевое, указатель на буфер, содержащий данные для расшифрования. Если установлен флаг CP_CRYPT_HASH_PACKET указатель на буфер, содержащий пакет. См. Шифрование и хэширование пакета . Если установлены флаги CP_CRYPT_HASH_PACKET и CP_CRYPT_DATA_IOVEC, указатель на массив структур CSP_iovec, определяющий пакет. См. Вектор ввода вывода . После расшифрования открытые данные помещаются в этот же буфер или передаются через массив структур CSP_iovec. Если установлены флаги CP_CRYPT_HASH_PACKET и CP_CHP_MULTIPACKET, указатель на массив структур CSP_Multipacket_DEC, задающий массив пакетов для параллельной обработки на платформах, поддерживающих SIMD архитектуру SSE_x, SSSE_x, AVX. См. Мультипакетная обработка .
pdwDataLen
[in/out] Если значение dwFlags нулевое, указатель на буфер, содержащий длину данных. Параметр pdwDataLen определяет число байтов шифртекста в буфере pbData. Через этот параметр функция возвращает указатель на число байтов открытого текста, помещённого в буфер pbData. Если установлен флаг CP_CRYPT_HASH_PACKET, размер буфера pbData в байтах. Если установлены флаги CP_CRYPT_HASH_PACKET и CP_CRYPT_DATA_IOVEC, передаётся число элементов массива CSP_iovec. Если установлены флаги CP_CRYPT_HASH_PACKET и CP_CHP_STARTMIX, по указателю pdwDataLen передаётся длина пакета включая блоб диверсификации ключей. Если установлены флаги CP_CRYPT_HASH_PACKET,CP_CRYPT_DATA_IOVEC и CP_CHP_STARTMIX, по указателю pdwDataLen передаётся число элементов вектора включая блоб диверсификации ключей (в этом варианте использования, блоб диверсификации должен передаваться отдельным первым элементом). Если установлены флаги CP_CRYPT_HASH_PACKET и CP_CHP_MULTIPACKET, указатель на число структур CSP_Multipacket_DEC.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_ALGID | Параметр AlgId определяет алгоритм, который не поддерживается криптопровайдером.
NTE_BAD_FLAGS | Величина dwFlags имеет некорректное значение, например, ненулевое значение при неустановленном флаге CP_CRYPT_HASH_PACKET.
NTE_BAD_DATA | Данные для расшифрования недействительны. В частности, в блочных режимах шифрования, если Final = FALSE, а длина шифртекста не кратна длине блока шифрования, возвращается данная ошибка. Эта ошибка также возвращается в блочных режимах шифрования, если используется дополнение (паддинг) PKCS#5, ISO 10126 или ANSI X.923, Final = TRUE, а дополнение блока не удовлетворяет условиям соответствующего дополнения. При шифровании пакета - ошибка формирования пакета.
NTE_BAD_LEN | Размер буфера недостаточен для полученного открытого текста.
NTE_PERM | Право расшифрования на данном ключе криптопровайдером не предоставлено.
NTE_BAD_KEY | Ключ недействителен.
NTE_BAD_HASH | Дескриптор хэша ошибочен. А также при расшифровании пакета с флагами CP_CHP_HASH_CHAIN, либо CP_CHP_HASH_PACKET рассчитанное значение хэш-функции не совпало со значением, полученным из пакета.
NTE_FAIL | Нарушение целостности ключей в ОЗУ. см. Дополнительные параметры и определения .

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCDecrypt .

См. также

CPEncrypt() ,CPGenKey() ,CPDecrypt в MS CSP World Wide Web link ,CryptDecrypt в MS CryptoAPI 2.0 World Wide Web link


Функции хэширования и ЭП

Функции хэширования и ЭП предназначены для вычисления значения хэш функции и формирования/проверки ЭП данных.

Функции | Описание
CPCreateHash | Функция CPCreateHash() инициализирует дескриптор нового объекта функции хэширования потока данных.
CPDestroyHash | Функция CPDestroyHash() удаляет объект функции хэширования.
CPDuplicateHash | Функция CPDuplicateHash() создаёт точную копию объекта функции хэширования, включая все его переменные, определяющие внутреннее состояние объекта функции хэширования.
CPGetHashParam | Функция CPGetHashParam() возвращает параметры объекта функции хэширования и значение функции хэширования.
CPHashData | Функция CPHashData() передаёт данные указанному объекту функции хэширования.
CPHashSessionKey | Функция CPHashSessionKey() передаёт криптографический ключ указанному объекту функции хэширования. Это позволяет хэшировать ключи сессии без передачи ключа приложению.
CPSetHashParam | Функция CPSetHashParam() устанавливает параметры объекта хэширования.
CPSignHash | Функция CPSignHash() возвращает значение электронной цифровой подписи от значения функции хэширования.
CPVerifySignature | Функция CPVerifySignature() осуществляет проверку цифровой подписи.


CPCreateHash

Функция CPCreateHash() инициализирует дескриптор нового объекта функции хэширования потока данных.

BOOL WINAPI CPCreateHash(
  HCRYPTPROV hProv,
  ALG_ID AlgId,
  HCRYPTKEY hKey,
  DWORD dwFlags,
  HCRYPTHASH * phHash
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
AlgId
[in] Идентификатор используемого алгоритма хэширования. В криптопровайдере определены следующие алгоритмы хэширования:
  • CALG_GR3411 - Алгоритм хэширования в соответствии с ГОСТ Р 34.11-94;
  • CALG_GR3411_2012_256 - Алгоритм хэширования в соответствии с ГОСТ Р 34.11-2012, длина выхода 256 бит.
  • CALG_GR3411_2012_512 - Алгоритм хэширования в соответствии с ГОСТ Р 34.11-2012, длина выхода 512 бит.
  • CALG_G28147_IMIT - Алгоритм имитозащиты в соответствии с ГОСТ 28147-89;
  • CALG_TLS1_MASTER_HASH - Объект, содержащий ключевую информацию для создания ключей CALG_TLS1_ENC_KEY и CALG_TLS1_MAC_KEY;
  • CALG_TLS1_MASTER_HASH_2012_256 - Объект, содержащий ключевую информацию для создания ключей CALG_TLS1_ENC_KEY и CALG_TLS1_MAC_KEY на основе алгоритма хэширования в соответствии с ГОСТ Р 34.11-2012;
  • CALG_PBKDF2_94_256 - Объект, содержащий ключевую информацию для выработки ключа из пароля на основе алгоритма хэширования в соответствии с ГОСТ Р 34.11-94, длина выхода 256 бит;
  • CALG_PBKDF2_2012_256 - Объект, содержащий ключевую информацию для выработки ключа из пароля на основе алгоритма хэширования в соответствии с ГОСТ Р 34.11-2012, длина выхода 256 бит;
  • CALG_PBKDF2_2012_512 - Объект, содержащий ключевую информацию для выработки ключа из пароля на основе алгоритма хэширования в соответствии с ГОСТ Р 34.11-2012, длина выхода 512 бит;
  • CALG_TLS1PRF - Алгоритм "производящей функции" (PRF), генерирующей блок данных произвольной длины на основе ключа, метки и бинарных данных.
  • CALG_TLS1PRF_2012_256 - Алгоритм "производящей функции" (PRF), генерирующей блок данных произвольной длины на основе ключа, метки и бинарных данных, базирующийся на алгоритме хэширования в соответствии с ГОСТ Р 34.11-2012.
  • CALG_GR3411_HMAC - Алгоритм ключевого хэширования на базе алгоритма ГОСТ Р 34.11-94 и сессионного ключа CALG_G28147.
  • CALG_GR3411_2012_256_HMAC - Алгоритм ключевого хэширования на базе алгоритма ГОСТ Р 34.11-2012 и сессионных ключей CALG_G28147/CALG_SYMMETRIC_512, длина выхода 256 бит.
  • CALG_GR3411_2012_512_HMAC - Алгоритм ключевого хэширования на базе алгоритма ГОСТ Р 34.11-2012 и сессионных ключей CALG_G28147/CALG_SYMMETRIC_512, длина выхода 512 бит.
  • CALG_EKEVERIFY_HASH - Алгоритм ключевого хэширования в протоколе взаимодействия с функциональным ключевым носителем. Ключ должен иметь тип CALG_PRO_AGREEDKEY_DH. Данные должны быть составлены в порядке, соответствующем полям структуры TOKEN_VERIFYDATA, за исключением поля Verify, и должны иметь длину sizeof(TOKEN_VERIFYDATA)- sizeof(DWORD). Данные должны подаваться на функцию хэширования одним блоком. Длина данных, возвращаемых через CPGetHashParam() – 4 байта.
  • CALG_MD5 - Алгоритм хэширования MD5 (RFC 1321).
  • CALG_SHA1 - Алгоритм хэширования SHA-1 (RFC 3174, FIPS PUB 180-1).
  • CALG_SHA_256 - Алгоритм хэширования SHA-256 (FIPS PUB 180-3).
  • CALG_SHA_384 - Алгоритм хэширования SHA-384 (FIPS PUB 180-3).
  • CALG_SHA_512 - Алгоритм хэширования SHA-512 (FIPS PUB 180-3).
  • CALG_UECMASTER_DIVERS - Объект, содержащий ключевую информацию ключа CALG_UECSYMMETRIC для диверсификации ключей карт с использованием CPCDeriveKey().
  • CALG_SHAREDKEY_HASH - Объект, содержащий ключевую информацию симметричного ключа для разложения в компоненты с использованием CPCDeriveKey().
  • CALG_FITTINGKEY_HASH - Объект, предназначен для сбора компонент в ключ CALG_UECSYMMETRIC с занесением в ключевой контейнер, если отсутствует AT_UECSYMMETRICKEY, либо в ключ CALG_G28147, CALG_UECSYMMETRIC_EPHEM, с использованием CPCHashSessionKey(), результирующий ключ производится функцией CPCDeriveKey().
  • CALG_GR3411_HMAC_FIXEDKEY - Алгоритм ключевого хэширования на базе алгоритма ГОСТ Р 34.11-94 с фиксированным сессионным ключом CALG_G28147. Ключ на вход не передается, а устанавливается после с помощью функции SetHashParam с параметром HP_HMAC_FIXEDKEY. Для использования в библиотеке IPsec.
  • CALG_GR3411_2012_256_HMAC_FIXEDKEY - Алгоритм ключевого хэширования на базе алгоритма ГОСТ Р 34.11-2012 с фиксированным сессионным ключом CALG_SYMMETRIC_512, длина выхода 256 бит. Ключ на вход не передается, а устанавливается после с помощью функции SetHashParam с параметром HP_HMAC_FIXEDKEY. Для использования в библиотеке IPsec.
  • CALG_GR3411_2012_512_HMAC_FIXEDKEY - Алгоритм ключевого хэширования на базе алгоритма ГОСТ Р 34.11-2012 с фиксированным сессионным ключом CALG_SYMMETRIC_512, длина выхода 512 бит. Ключ на вход не передается, а устанавливается после с помощью функции SetHashParam с параметром HP_HMAC_FIXEDKEY. Для использования в библиотеке IPsec.
  • CALG_GR3411_PRFKEYMAT - Алгоритм "производящей функции" (PRF) на базе алгоритма ГОСТ Р 34.11-94 и сессионного ключа CALG_G28147, генерирующей блок данных произвольной длины на основе бинарных данных (seed). Seed устанавливается через SetHashParam HP_PRFKEYMAT_SEED.
  • CALG_GR3411_2012_256_PRFKEYMAT - Алгоритм "производящей функции" (PRF) на базе алгоритма ГОСТ Р 34.11-2012 и сессионных ключей CALG_G28147/CALG_SYMMETRIC_512, генерирующей блок данных произвольной длины на основе бинарных данных (seed). Seed устанавливается через SetHashParam HP_PRFKEYMAT_SEED.
  • CALG_GR3411_2012_512_PRFKEYMAT - Алгоритм "производящей функции" (PRF) на базе алгоритма ГОСТ Р 34.11-2012 и сессионных ключей CALG_G28147/CALG_SYMMETRIC_512, генерирующей блок данных произвольной длины на основе бинарных данных (seed). Seed устанавливается через SetHashParam HP_PRFKEYMAT_SEED.
hKey
[in] Если используется алгоритм имитозащиты по ГОСТ 28147-89 (CALG_G28147_IMIT), в этом параметре передаётся ключ сессии для объекта функции хэширования.

Если используется алгоритм CALG_TLS1_MASTER_HASH или CALG_TLS1_MASTER_HASH_2012_256, в этом параметре передается master_secret (ключ типа CALG_TLS1_MASTER), на основе которого будет создана ключевая информация по следующей формуле:

      key_block = PRF(SecurityParameters.master_secret,
                         "key expansion",
                         SecurityParameters.server_random +
                         SecurityParameters.client_random);
Предварительно следует установить KP_CLIENT_RANDOM и KP_SERVER_RANDOM.

Если используется алгоритм CALG_TLS1PRF или CALG_TLS1PRF_2012_256, в этом параметре передается ключ типа CALG_TLS1_MASTER.

Для алгоритмов хэширования типа ГОСТ Р 34.11-94 и ГОСТ Р 34.11-2012 этот параметр должен быть установлен в ноль.
dwFlags
[in] Значения флагов. При создании объекта HMAC возможно указать флаг CP_REUSABLE_HMAC для повышения эффективности повторного использования.
phHash
[out] Адрес по которому функция копирует дескриптор нового объекта функции хэширования.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_ALGID | Параметр AlgId определяет алгоритм, который не поддерживается криптопровайдером.
NTE_BAD_FLAGS | Величина dwFlags имеет ненулевое значение.
NTE_BAD_KEY | Дескриптор исходного ключа ошибочен либо ключ не действителен.
NTE_NO_MEMORY | Криптопровайдер во время операции исчерпал память.
NTE_FAIL | Ошибка при считывании данных из системного реестра. см. Дополнительные параметры и определения .

Примечания

Использование алгоритмов CALG_MD5, CALG_SHA_256, CALG_SHA_384, CALG_SHA_512 не входит в функционал СКЗИ КриптоПро CSP 4.0, относящийся к действию сертификата ФСБ.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCCreateHash .

См. также

CPDestroyHash() ,CPHashData() ,CPCreateHash в MS CSP World Wide Web link ,CryptCreateHash в MS CryptoAPI 2.0 World Wide Web link


CPDestroyHash

Функция CPDestroyHash() удаляет объект функции хэширования.

BOOL WINAPI CPDestroyHash(
  HCRYPTPROV hProv,
  HCRYPTHASH hHash
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
hHash
[in] Дескриптор удаляемого объекта функции хэширования.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возврата | Описание
NTE_BAD_TYPE | Тип алгоритма hHash ошибочен.
NTE_BAD_HASH | Дескриптор хэша ошибочен.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCDestroyHash .

См. также

CPCreateHash() ,CPDestroyHash в MS CSP World Wide Web link ,CryptDestroyHash в MS CryptoAPI 2.0 World Wide Web link


CPDuplicateHash

Функция CPDuplicateHash() создаёт точную копию объекта функции хэширования, включая все его переменные, определяющие внутреннее состояние объекта функции хэширования.

BOOL WINAPI CPDuplicateHash(
  HCRYPTPROV hProv,
  HCRYPTHASH hHash,
  DWORD * pdwReserved,
  DWORD dwFlags,
  HCRYPTHASH * phHash
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
hHash
[in] Дескриптор объекта функции хэширования.
pdwReserved
[in] Параметр зарезервирован для будущего использования и должен быть NULL.
dwFlags
[in] Параметр зарезервирован для будущего использования и должен быть нулевым.
phHash
[out] Адрес, по которому функция копирует дескриптор нового объекта функции хэширования.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_HASH | Дескриптор исходного хэша ошибочен.
NTE_NO_MEMORY | Криптопровайдер во время операции исчерпал память.
NTE_BAD_FLAGS | Параметр dwFlags имеет ненулевое значение.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCDuplicateHash .

См. также

CPDestroyHash() ,CPDuplicateHash в MS CSP World Wide Web link ,CryptDuplicateHash в MS CryptoAPI 2.0 World Wide Web link


CPGetHashParam

Функция CPGetHashParam() возвращает параметры объекта функции хэширования и значение функции хэширования.

BOOL WINAPI CPGetHashParam(
  HCRYPTPROV hProv,
  HCRYPTHASH hHash,
  DWORD dwParam,
  BYTE * pbData,
  DWORD * pdwDataLen,
  DWORD dwFlags
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
hHash
[in] Дескриптор объекта функции хэширования, параметры которого определяются.
dwParam
[in] Параметр, принимающий следующие возможные значения:
Значение dwParam | Содержимое буфера pbData
HP_ALGID | Алгоритм функции хэширования. Идентификатор алгоритма (ALG_ID), соответствующий данному объекту функции хэширования. Возвращается через буфер pbData. В pdwDataLen будет возвращена величина 4.
HP_HASHSIZE | Размер значения функции хэширования. Величина DWORD, определяющая число байтов в значении функции хэширования, будет возвращена через буфер pbData. В pdwDataLen будет возвращена величина 4.
HP_HASHVAL Значение функции хэширования в little-endian порядке байт в соответствии с типом GostR3411-94-Digest CPCMS [RFC 4490]. Вычисленное значение функции хэширования будет возвращено через буфер pbData. Длина значения функции хэширования будет возвращена в pdwDataLen.
Во время вызова функции объект хэша "закрывается".
Для ГОСТ Р 34.11-94 и ГОСТ Р 34.11-2012 (и HMAC-ов на их основе) проводится дополнение до размера блока (если требуется), исполняются шаговые функции для последнего блока (если требуется), для длины и для контрольной суммы.
Для ГОСТ 28147-89 в режиме имитовставки проводится дополнение до размера блока (если требуется), и исполняется шаговая функции для последнего блока (если требуется).
Расчёт хэш-функции может быть продолжен с помощью:
  • последующего вызова *SetHashParam(HP_OPEN, TRUE) для CSP 3.6 и выше;
  • предварительного вызова *DuplicateHash() - стандартный для Microsoft способ;
HP_R2_SIGN Возвращает значение R2 в алгоритме распределённой подписи, вырабатываемой с использованием функционального ключевого носителя. Через параметр pbData возвращается значение данных - точка эллиптической кривой в аффинных координатах (X,Y), длина данных – 64 бита.
Закрывает объект функции хэшироваия. Специфика протокола ООО "КРИПТО-ПРО" взаимодействия с функциональным ключевым носителем.
HP_R_SIGN Возвращает значение R в алгоритме распределённой подписи, вырабатываемой с использованием функционального ключевого носителя. Через параметр pbData возвращается значение данных - точка эллиптической кривой в аффинных координатах (X,Y), длина данных – 64 бита.
Специфика протокола ООО "КРИПТО-ПРО" взаимодействия с функциональным ключевым носителем.
HP_SHAREDMODE | Возвращает значение числа от 2 до 5 компонент, на которые раскладывается ключ объектом CALG_SHAREDKEY_HASH, либо собирается ключ объектом CALG_FITTINGKEY_HASH.
HP_IKE_SPI_COOKIE | Возвращает 32-35 байты значения хэша (при нумерации 0..63) для объектов типа CALG_GR3411_2012_512 и CALG_GR3411_2012_512_HMAC.
*pbData
[out] Указатель на буфер данных параметра. Функция копирует соответствующие параметру данные в буфер. Формат этих данных зависит от значения dwParam. Если параметр - NULL, то данные не копируются. Требуемый размер буфера в байтах возвращается в pdwDataLen. Подробнее см. Возвращение данных неопределённой длины.
*pdwDataLen
[in/out] Указатель на буфер, содержащий длину данных параметра. При вызове функции указанный параметр содержит число байтов в буфере pbData. После её исполнения параметр будет установлен числом байтов данных параметра, скопированных в буфер pbData. Если буфер, соответствующий pbData, недостаточно большой, чтобы в него копировать запрошенные данные, будет возвращён код ошибки ERROR_MORE_DATA через функцию SetLastError(). В этом случае требуемый размер буфера возвращается в pdwDataLen. Если функция завершается с кодом ошибки, отличным от ERROR_MORE_DATA, в этом параметре возвращается ноль.
dwFlags
[in] Значения флагов. Параметр зарезервирован для будущего использования и должен быть нулевым.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_HASH | Дескриптор хэша ошибочен.
ERROR_MORE_DATA | Размер буфера pbData недостаточен для копирования затребованных данных.
NTE_BAD_FLAGS | Параметр dwFlags имеет ненулевое значение.
NTE_BAD_TYPE | Параметр dwParam передаёт неизвестное значение параметра.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCGetHashParam .

См. также

CPCreateHash() ,CPGetKeyParam() ,CPSetHashParam() ,CPGetHashParam в MS CSP World Wide Web link ,CryptGetHashParam в MS CryptoAPI 2.0 World Wide Web link


CPHashData

Функция CPHashData() передаёт данные указанному объекту функции хэширования.

BOOL WINAPI CPHashData(
  HCRYPTPROV hProv,
  HCRYPTHASH hHash,
  CONST BYTE * pbData,
  DWORD dwDataLen,
  DWORD dwFlags
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
hHash
[in] Дескриптор объекта функции хэширования. Приложение получает этот дескриптор, используя функцию CPCreateHash().
pbData
[in] Если значение dwFlags нулевое, указатель на буфер, содержащий данные для хэширования. Если установлен флаг CP_HASH_DATA_IOVEC указатель на массив структур CSP_iovec. См. Вектор ввода вывода .
dwDataLen
[in] Если значение dwFlags нулевое, число байтов хэшируемых данных. Если установлен флаг CP_HASH_DATA_IOVEC, число элементов массива CSP_iovec.
dwFlags
[in] Значения флагов. Параметр определяет способ обработки фрагмента данных в потоке. Нулевое значение соответствует хэшированию фрагмента данных потока, флаг CP_HASH_DATA_IOVEC соответствует обработке данных в форме вектора ввода/вывода. См. Вектор ввода вывода .

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_ALGID | Ключ сессии hKey определяет алгоритм, который данный криптопровайдер не поддерживает.
NTE_BAD_HASH | Дескриптор хэша ошибочен.
NTE_BAD_HASH_STATE | Была сделана попытка добавить данные к объекту функции хэширования, который уже отмечен как "закрытый".
NTE_BAD_KEY | Используется алгоритм хэширования (CALG_G28147_IMIT), но сессионный ключ удалён прежде, чем действие хэширования завершено.
NTE_BAD_FLAGS | Величина dwFlags имеет значение, отличное от нулевого либо от CP_HASH_DATA_IOVEC.
NTE_BAD_LEN | Величина dwDataLen при установленном флаге CP_HASH_DATA_IOVEC имеет значение, превосходящее CSP_UIO_MAXIOV.
NTE_FAIL | Нарушение целостности ключей в ОЗУ.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCHashData .

См. также

CPCreateHash() ,CPHashSessionKey() ,CPHashData в MS CSP World Wide Web link ,CryptHashData в MS CryptoAPI 2.0 World Wide Web link


CPHashSessionKey

Функция CPHashSessionKey() передаёт криптографический ключ указанному объекту функции хэширования. Это позволяет хэшировать ключи сессии без передачи ключа приложению.

BOOL WINAPI CPHashSessionKey(
  HCRYPTPROV hProv,
  HCRYPTHASH hHash,
  HCRYPTKEY hKey,
  DWORD dwFlags
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
hHash
[in] Дескриптор объекта функции хэширования. Приложение получает этот дескриптор, используя функцию CPCreateHash().
hKey
[in] Дескриптор хэшируемого ключа сессии. Хэш типа CALG_FITTINGKEY_HASH собирает ключи в единый ключ, создаваемый функцией CPDeriveKey().
dwFlags
[in] Значение CRYPT_LITTLE_ENDIAN соответствует хэшированию ключа в порядке байт, определяемым ГОСТ 28147-89, нулевое значение соответствует хэшированию в обратном порядке байт ключа.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возврата | Описание
NTE_BAD_HASH | Дескриптор хэша ошибочен.
NTE_BAD_ALGID | Параметр AlgId определяет алгоритм, который не поддерживается криптопровайдером.
NTE_BAD_HASH_STATE | Была сделана попытка добавить данные к объекту функции хэширования, который уже отмечен как "закрытый".
NTE_BAD_KEY | Тип хэшируемого ключа не соответствует ALG_TYPE_BLOCK.

Примечания

Функция CPHashSessionKey() добавляет к объекту функции хэширования только значение сессионного ключа hKey. Приложение должно самостоятельно добавлять к этому объекту дополнительные величины, такие как стартовый вектор шифрования и т.п.

Использование функции с dwFlags равным 0 не рекомендуется - поведение не определено.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCHashSessionKey .

См. также

CPCreateHash() ,CPGenKey() ,CPHashData() ,CPHashSessionKey в MS CSP World Wide Web link ,CryptHashSessionKey в MS CryptoAPI 2.0 World Wide Web link


CPSetHashParam

Функция CPSetHashParam() устанавливает параметры объекта хэширования.

BOOL WINAPI CPSetHashParam(
  HCRYPTPROV hProv,
  HCRYPTHASH hHash,
  DWORD dwParam,
  BYTE * pbData,
  DWORD dwFlags
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
hHash
[in] Дескриптор объекта хэширования, параметры которого устанавливаются.
dwParam
[in] Параметр, принимающий следующие возможные значения:
Значение dwParam | Содержимое буфера pbData
HP_HASHVAL | Устанавливается для объекта функции хэширования типа CALG_GR3411, CALG_GR3411_2012_256 и CALG_GR3411_2012_512. Величина, 32 байта для объектов типа CALG_GR3411 и CALG_GR3411_2012_256, 64 байта для объектов типа CALG_GR3411_2012_512, в little-endian порядке байт в соответствии с типом GostR3411-94-Digest CPCMS [RFC 4490], должна быть установлена в буфер pbData.
HP_HASHSIZE | Устанавливается для объекта функции хэширования типа CALG_G28147_IMIT. В буфер pbData записывается величина DWORD, определяющая число байтов имитовставки в диапазоне от 1 до 4. По умолчанию длина имитовставки равна 4 байтам.
KP_HASHOID | Идентификатор функции хэширования. Строка, заканчивающаяся нулем. Не допускается задавать для объектов типа CALG_GR3411_HMAC / CALG_GR3411_HMAC34, CALG_GR3411_2012_256_HMAC / CALG_GR3411_2012_512_HMAC и CALG_GR3411_2012_256 / CALG_GR3411_2012_512.
HP_TLS1PRF_SEED | Составляющая аргумента функции GOSTR3411_PRF. Принимает различные значения в сообщениях клиента и сервера при реализации TLS Handshake Protocol. Задается в виде структуры CRYPT_DATA_BLOB.
HP_TLS1PRF_LABEL | Составляющая аргумента функции GOSTR3411_PRF. Принимает различные значения в сообщениях клиента и сервера при реализации TLS Handshake Protocol. Задается в виде структуры CRYPT_DATA_BLOB.
HP_PBKDF2_SALT | Задает синхропосылку размерности от 8 до 32 байт для объекта хэша типа CALG_PBKDF2_94_256, CALG_PBKDF2_2012_256 и CALG_PBKDF2_2012_512. Задается в виде структуры CRYPT_DATA_BLOB.
HP_PBKDF2_PASSWORD | Задает пароль для объекта хэша типа CALG_PBKDF2_94_256, CALG_PBKDF2_2012_256 и CALG_PBKDF2_2012_512. Задается в виде структуры CRYPT_DATA_BLOB.
HP_PBKDF2_COUNT | Устанавливается для объекта функции хэширования типа CALG_PBKDF2_94_256, CALG_PBKDF2_2012_256 и CALG_PBKDF2_2012_512. В буфер pbData записывается величина DWORD, определяющая число итераций алгоритма. По умолчанию количество итераций равно 2000, минимальное допустимое значение параметра 1000.
HP_OPEN | Если через параметр pbData передаётся величина FALSE типа DWORD, производит повторную инициализацию объекта хэша типа CALG_GR3411, CALG_GR3411_HMAC, CALG_GR3411_HMAC34, CALG_G28147_IMIT, CALG_GR3411_2012_256, CALG_GR3411_2012_512, CALG_GR3411_2012_256_HMAC, CALG_GR3411_2012_512_HMAC в случае, если он закрыт. Если в pbData передаётся величина TRUE типа DWORD, закрытый объект функции хэширования типа CALG_GR3411 или CALG_G28147_IMIT открывается для дальнейшего хэширования данных.
HP_KEYMIXSTART | Осуществляет диверсификацию ключа, ассоциированного с объектом хэширования, по алгоритму CALG_PRO_DIVERS. Через параметр pbData передаётся блоб диверсификации ключа в форме CRYPT_DATA_BLOB, см. CPCImportKey(). Допускается многократный вызов с различными параметрами диверсификации.
HP_KEYSPEC_SIGN | Задает ключевую пару из открытого контейнера, на которой будут производиться вычисления в алгоритме распределенной подписи. Через параметр pbData передаётся значение типа ALG_ID, которое может быть равным AT_KEYEXCHANGE или AT_SIGNATURE. Установка данного параметра обязательно должна предшествовать применению алгоритма распределенной подписи. Специфика протокола ООО "КРИПТО-ПРО" взаимодействия с функциональным ключевым носителем.
HP_R2_SIGN | Устанавливает значение R2 в алгоритме распределённой подписи, вырабатываемой с использованием функционального ключевого носителя. Через параметр pbData передаётся структура типа CRYPT_HASH_BLOB_EX, где в качестве данных выступает точка эллиптической кривой в аффинных координатах (X,Y). Закрывает объект функции хэшироваия. Специфика протокола ООО "КРИПТО-ПРО" взаимодействия с функциональным ключевым носителем.
HP_R_SIGN | Устанавливает значение R в алгоритме распределённой подписи, вырабатываемой с использованием функционального ключевого носителя. Через параметр pbData передаётся типа CRYPT_HASH_BLOB_EX, где в качестве данных выступает точка эллиптической кривой в аффинных координатах (X,Y). Специфика протокола ООО "КРИПТО-ПРО" взаимодействия с функциональным ключевым носителем.
HP_S2_SIGN | Устанавливает значение ЭП, выработанное на стороне функционального ключевого носителя. Через параметр pbData передаётся значение типа CRYPT_HASH_BLOB_EX, где в качестве данных выступает значение ЭП (R,S2). Специфика протокола ООО "КРИПТО-ПРО" взаимодействия с функциональным ключевым носителем.
HP_SHAREDMODE | Устанавливает значение числа от 2 до 5 компонент, на которые раскладывается ключ объектом CALG_SHAREDKEY_HASH, либо собирается ключ объектом CALG_FITTINGKEY_HASH.
HP_HMAC_FIXEDKEY | Устанавливает значение ключа для объекта хэша типа CALG_GR3411_HMAC_FIXEDKEY, CALG_GR3411_2012_256_HMAC_FIXEDKEY и CALG_GR3411_2012_512_HMAC_FIXEDKEY. Через параметр pbData передаётся ключ в форме CRYPT_DATA_BLOB. Если размер переданных в блобе данных меньше размера соответствующего ключа, то ключ дополняется нулями, иначе - в качестве ключа устанавливается результат хэширования переданных данных.
HP_PRFKEYMAT_SEED | Устанавливает значение seed для объекта хэша типа CALG_GR3411_PRFKEYMAT, CALG_GR3411_2012_256_PRFKEYMAT и CALG_GR3411_2012_512_PRFKEYMAT. Через параметр pbData передаётся seed в форме CRYPT_DATA_BLOB.
pbData
[in] Указатель на буфер данных параметра. При вызове функции буфер содержит данные, соответствующие значению параметра в dwParam. Формат данных зависит от типа параметра dwParam.
dwFlags
[in] Значения флагов. Параметр зарезервирован для будущего использования и должен быть нулевым.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_HASH | Дескриптор хэша ошибочен.
NTE_BAD_FLAGS | Параметр dwFlags имеет ненулевое значение.
NTE_BAD_TYPE | Параметр dwParam передаёт неизвестное значение параметра.
NTE_BAD_HASH_STATE | Была сделана попытка получить значение функции хэширования для "не закрытого" объекта функции хэширования.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCSetHashParam .

См. также

CPCreateHash() ,CPGetHashParam() ,CPSignHash() ,CPSetHashParam в MS CSP World Wide Web link ,CryptSetHashParam в MS CryptoAPI 2.0 World Wide Web link


CPSignHash

Функция CPSignHash() возвращает значение электронной цифровой подписи от значения функции хэширования.

BOOL WINAPI CPSignHash(
  HCRYPTPROV hProv,
  HCRYPTHASH hHash,
  DWORD dwKeySpec,
  LPCWSTR sDescription,
  DWORD dwFlags,
  BYTE * pbSignature,
  DWORD * pdwSigLen
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
hHash
[in] Дескриптор объекта функции хэширования, который будет подписан.
Для хэш с алгоритмами CALG_MD5, CALG_SHA1, CALG_SHA_256, CALG_SHA_384, CALG_SHA_512 функция может отработать успешно, но значение подписи всегда будет неопределённым.
dwKeySpec
[in] Тип ключевой пары, использующейся при подписи значения функции хэширования. Могут быть использованы следующие значения:
Значение | Описание
AT_KEYEXCHANGE | Ключевая пара обмена
AT_SIGNATURE | Ключевая пара цифровой подписи
sDescription
[in] Описание подписываемых данных, добавляемых к объекту hash перед тем, как будет произведена подпись. При проверке подписи функцией CPVerifySignature() необходимо использовать то же описание подписанных данных. Это гарантирует, что подписывающая сторона и проверяющая знают то, что подписывается или проверяется. Если описание не включается в подпись, этот параметр устанавливается в NULL.

Параметр сохранён для совместимости со спецификацией Microsoft Cryptographic Service Provider. С целью предотвращения уязвимости безопасности ЭП использовать этот параметр не рекомендуется. Он должен быть установлен в NULL.
dwFlags
[in] Значения флагов. Параметр зарезервирован для будущего использования и должен быть нулём.
pbSignature
[in] Указатель на буфер, через который возвращается значение подписи. Если через этот параметр передаётся NULL, то подпись не вычисляется. В этом случае требуемый размер буфера (в байтах) возвращается через параметр pdwSigLen.
pdwSigLen
[in/out] Указатель на буфер, содержащий длину данных подписи. При вызове функции указанный параметр должен содержать число байтов в буфере pbSignature. После её исполнения параметр будет установлен числом байтов данных, скопированных в буфер pbSignature. Если буфер, соответствующий pbSignature, недостаточно большой, чтобы в него копировать подпись, будет возвращён код ошибки ERROR_MORE_DATA через функцию SetLastError(). В этом случае требуемый размер буфера возвращается в pdwSigLen. Если эта функция завершается с кодом ошибки, отличным от ERROR_MORE_DATA, в этом параметре возвращается ноль. Подпись для ключей ГОСТ Р 34.10-2001 возвращается как описано CPPK (RFC 4491), но в обратном порядке байт. Например, подпись сертификата п. 4.2 будет возвращена:

 {
 0xE2, 0xDE, 0x33, 0x1C, 0xB5, 0xD5, 0x31, 0xB1, 0xDA, 0xF4, 0x20, 0x62, 0x17, 0x89, 0x89, 0x68,
 0x77, 0x55, 0x93, 0x36, 0xDD, 0xF3, 0x93, 0xB5, 0x71, 0xEC, 0x1B, 0x8D, 0x6E, 0x17, 0xDE, 0xC1,
 0xDD, 0x3F, 0x54, 0xBC, 0x4F, 0x45, 0x16, 0x31, 0xED, 0xDE, 0x2E, 0x44, 0x7C, 0x64, 0xAA, 0xC3,
 0xD2, 0x6D, 0x53, 0xFB, 0xE9, 0xD5, 0xA7, 0xEC, 0xA9, 0x27, 0xB7, 0x44, 0x09, 0xC9, 0x2F, 0x3C
 }

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError().
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_ALGID | Дескриптор hHash определяет алгоритм, который данный криптопровайдер не поддерживает.
NTE_BAD_FLAGS | dwFlags параметр отличен от нуля, либо параметр dwKeySpec содержит ошибочную величину.
NTE_BAD_HASH | Дескриптор хэша ошибочен.
NTE_NO_KEY | Закрытый ключ, указанный dwKeySpec, не существует.
NTE_NO_MEMORY | Криптопровайдер во время операции исчерпал память.
ERROR_MORE_DATA | pbSignature буфер мал для копирования затребованных данных.
NTE_FAIL | Нарушение целостности ключей в ОЗУ. см. Дополнительные параметры и определения .
SCARD_W_CANCELLED_BY_USER | Пользователь прервал операцию нажатием клавиши Cancel
SCARD_W_WRONG_CHV | Пользователь ввёл неправильный пароль или пароль, установленный функцией SetProvParam(), неправильный
SCARD_E_INVALID_CHV | Пользователь ввёл пароль с нарушением формата или пароль, установленный функцией SetProvParam(), имеет неправильный формат. Например, пароль имеет недопустимую длину или содержит недопустимые символы.
SCARD_W_CHV_BLOCKED | Ввод Pin-кода был заблокирован смарт-картой, т.к. исчерпалось количество попыток, разрешенное картой для ввода.
NTE_SILENT_CONTEXT | Операция не может быть выполнена без пользовательского интерфейса.
SCARD_W_REMOVED_CARD | Носитель контейнера был удален из считывателя

Примечания

Перед вызовом функции CPSignHash() необходимо получить дескриптор объекта хэширования при помощи функции CPCreateHash(). После этого используется функция CPHashData() или CPHashSessionKey() чтобы добавить данные или ключи сессии к объекту хэширования.

Функция CPSignHash() выполняет следующие внутренние шаги:

  • объект функции хэширования "закрывается”; извлекается значение функции хэширования;
  • значение функции хэширования дополняется, как это требуется алгоритмом подписи;
  • вычисляется фактическое значение подписи.

    После того, как объект функции хэширования подписан, приложение не может добавлять к нему новые данные. Поэтому вызовы функций CPHashData() или CPHashSessionKey() приведут к ошибке. Однако, дополнительные вызовы функций CPDeriveKey(), CPGetHashParam(), CPSignHash() и CPVerifySignature() будут успешными. Эти функции будут работать с подписанным объектом функции хэширования. Приложение должно удалить объект функции хэширования при помощи функции CPDestroyHash().

При использовании ключей алгоритма ГОСТ Р 34.10-2001 для формирования электронной подписи необходимо использовать алгоритм хэширования ГОСТ Р 34.11-94.

При использовании ключей алгоритма ГОСТ Р 34.10-2012 длины 256 бит для формирования электронной подписи необходимо использовать алгоритм хэширования ГОСТ Р 34.11-2012 (256 бит).

При использовании ключей алгоритма ГОСТ Р 34.10-2012 длины 512 бит для формирования электронной подписи необходимо использовать алгоритм хэширования ГОСТ Р 34.11-2012 (512 бит).

Использование алгоритмов CALG_MD5, CALG_SHA_256, CALG_SHA_384, CALG_SHA_512 не входит в функционал СКЗИ КриптоПро CSP 4.0, относящийся к действию сертификата ФСБ.

Рекомендуется, по возможности, непосредственно после формирования подписи осуществить ее проверку.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCSignHash .

См. также

CPCreateHash() ,CPDestroyHash() ,CPHashData() ,CPHashSessionKey() ,CPVerifySignature() ,CPSignHash в MS CSP World Wide Web link ,CryptSignHash в MS CryptoAPI 2.0 World Wide Web link


CPVerifySignature

Функция CPVerifySignature() осуществляет проверку цифровой подписи.

BOOL WINAPI CPVerifySignature(
  HCRYPTPROV hProv,
  HCRYPTHASH hHash,
  CONST BYTE * pbSignature,
  DWORD dwSigLen,
  HCRYPTKEY hPubKey,
  LPCWSTR sDescription,
  DWORD dwFlags
);

Аргументы

hProv
[in] Дескриптор криптопровайдера. Получается при помощи функции CPAcquireContext().
hHash
[in] Дескриптор объекта функции хэширования, подпись которого проверяется.
Для хэш с алгоритмами CALG_MD5, CALG_SHA1, CALG_SHA_256, CALG_SHA_384, CALG_SHA_512 функция имеет неопределённое поведение.
pbSignature
[in] Указатель на буфер, содержащий значение проверяемой подписи.
dwSigLen
[in] Длина (в байтах) значения подписи.
hPubKey
[in] Дескриптор открытого ключа проверяемой подписи. Недопустимо использование одного ключа в многопоточной обработке. Для организации многопоточной обработки необходимо размножать ключ с использованием функции CPCDuplicateKey().
sDescription
[in] Описание подписанных данных идентичное описанию, использованному при создании подписи. Это должна быть точно та же самая последовательность, которая использовалась в функции CPSignHash() при создании подписи. Если эта последовательность не соответствует использованной в функции CPSignHash(), проверка подписи сообщит, что подпись не верна.
dwFlags
[in] Значения флагов. Параметр зарезервирован для будущего использования и должен быть нулевым.

Возвращаемые значения

При успешном завершении функция возвращает TRUE, в противном случае возвращается FALSE. Если возвращается FALSE, соответствующий код ошибки (см. таблицу) может быть получен через функцию GetLastError.
Коды возврата | Описание
ERROR_INVALID_PARAMETER | Один из параметров содержит некорректное значение. Чаще всего это некорректный указатель.
NTE_BAD_ALGID | Дескриптор hHash определяет алгоритм, который этот криптопровайдер не поддерживает.
NTE_BAD_FLAGS | dwFlags параметр отличен от нуля.
NTE_BAD_KEY | hPubKey параметр содержит дескриптор на недопустимый открытый ключ.
NTE_BAD_HASH | Дескриптор хэша ошибочен.
NTE_BAD_SIGNATURE | Проверка подписи не прошла (могли измениться подписанные данные, или значение подписи, открытый ключ был определён ошибочно параметром hPubKey). Эта ошибка может быть возвращена также, если алгоритмы хэширования или подписи не соответствуют тем, с помощью которых вычислялась подпись.
NTE_NO_MEMORY | Криптопровайдер во время операции исчерпал память.
NTE_FAIL | Нарушение целостности ключей в ОЗУ.
RPE_CORRUPT_KEYPAIR_INFO | Нарушение целостности ключей.

Примечания

Функция CPVerifySignature выполняет следующие внутренние шаги:

  • если параметр описания sDescription поддержан, он добавляется к объекту функции хэширования;
  • объект функции хэширования "закрывается" и значение функции хэширования извлекается;
  • значение функции хэширования дополняется, как это требуется алгоритмом подписи;
  • осуществляется проверка подписи c использованием открытого ключа hPubKey;
  • если подпись, переданная через буфер pbSignature, и вычисленное значение подписи не совпадают, возвращается код ошибки NTE_BAD_SIGNATURE.

    После того, как объект функции хэширования подписан, приложение не может добавлять к нему новые данные. Поэтому вызовы функций CPHashData() или CPHashSessionKey() приведут к ошибке. Однако, дополнительные вызовы функций CPDeriveKey(), CPGetHashParam(), CPSignHash() и CPVerifySignature() будут успешными. Эти функции будут работать с подписанным объектом функции хэширования. Приложение должно удалить объект функции хэширования при помощи функции CPDestroyHash().

При использовании ключей алгоритма ГОСТ Р 34.10-2001 для проверки электронной подписи необходимо использовать алгоритм хэширования ГОСТ Р 34.11-94.

При использовании ключей алгоритма ГОСТ Р 34.10-2012 длины 256 бит для проверки электронной подписи необходимо использовать алгоритм хэширования ГОСТ Р 34.11-2012 (256 бит).

При использовании ключей алгоритма ГОСТ Р 34.10-2012 длины 512 бит для проверки электронной подписи необходимо использовать алгоритм хэширования ГОСТ Р 34.11-2012 (512 бит).

Использование алгоритмов CALG_MD5, CALG_SHA_256, CALG_SHA_384, CALG_SHA_512 не входит в функционал СКЗИ КриптоПро CSP 4.0, относящийся к действию сертификата ФСБ.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле wincsp.h.
Ядро ОС: Вместо неё используется аналогичная функция CPCVerifySignature .

См. также

CPCreateHash() ,CPHashData() ,CPSignHash() ,CPVerifySignature в MS CSP World Wide Web link ,CryptVerifySignature в MS CryptoAPI 2.0 World Wide Web link


Структуры данных

Предназначены для взаимодействия с программами пользователя, непосредственно использующими "КриптоПро CSP 4.0".

  • Переключатели кода
  • Шифрование и хэширование пакета
  • Вспомогательные макросы описания структуры пакета
  • Вектор ввода вывода
  • Мультипакетная обработка
Структуры | Описание
_PUBLICKEYSTRUC | Структура PUBLICKEYSTRUC, также известная, как структура BLOBHEADER, указывает тип ключевого блоба и алгоритм ключа, находящегося в нём. Экземпляр этой структуры находится в начале поля pbData каждого ключевого блоба.
_PROV_PP_VERSION_EX | Структура описывает версию СКЗИ, ПКЗИ, тип сборки, аппаратную архитектуру и ОС, для которой предназначен продукт.
_SELFTEST_HEADER | Заголовок результата встроенного тестирования и контроля целостности СКЗИ.
_CPU_INFO | Структура описывает время работы (тики) процессора в простое, режиме ядра, пользовательском режиме, Nice режиме, и полное время работы процессора.
_SELFTEST_CHECKSUM_ELEMENT | Результат контроля целостности модуля.
_PROV_PP_SELFTEST | Результат встроенного тестирования и контроля целостности СКЗИ.
_CRYPT_SIMPLEBLOB_HEADER | Структура CRYPT_SIMPLEBLOB_HEADER является расширением структуры BLOBHEADER и находится в начале поля pbData ключевого блоба типа SIMPLEBLOB для ключей "КриптоПро CSP".
_CRYPT_SIMPLEBLOB | Псевдоструктура (т. е. недоопределенная структура) CRYPT_SIMPLEBLOB полностью описывает ключевой блоб типа SIMPLEBLOB для ключей "КриптоПро CSP".
_CRYPT_SIMPLEBLOB_512 | Псевдоструктура (т. е. недоопределенная структура) CRYPT_SIMPLEBLOB полностью описывает ключевой блоб типа SIMPLEBLOB для ключей "КриптоПро CSP".
_CRYPT_OPAQUEBLOB | Псевдоструктура (т. е. недоопределенная структура) CRYPT_OPAQUEBLOB полностью описывает ключевой блоб типа OPAQUEKEYLOB для ключей "КриптоПро CSP".
_CRYPT_PUBKEYPARAM | Структура CRYPT_PUBKEYPARAM содержит признак ключей по ГОСТ Р 34.10-2001.
_CRYPT_PUBKEY_INFO_HEADER | Структура CRYPT_PUBKEY_INFO_HEADER содержит заголовок блоба открытого ключа или блоба ключевой пары по ГОСТ Р 34.10-2001.
_CRYPT_PUBLICKEYBLOB | Псевдоструктура CRYPT_PUBLICKEYBLOB полностью описывает ключевой блоб типа PUBLICKEYBLOB для ключей "КриптоПро CSP".
_CRYPT_PRIVATEKEYBLOB | Псевдоструктура CRYPT_PRIVATEKEYBLOB полностью описывает ключевой блоб типа PRIVATEKEYBLOB для ключей "КриптоПро CSP".
_CRYPT_DIVERSBLOBHEADER | Структура CRYPT_DIVERSBLOBHEADER описывает блоб типа DIVERSBLOB для процедуры диверсификации ключей КриптоПро CSP.
_CRYPT_DIVERSBLOB | Структура CRYPT_DIVERSBLOB описывает блоб типа DIVERSBLOB для процедуры диверсификации ключей КриптоПро CSP.
_CRYPT_KDF_TREE_DIVERSBLOB_HEADER | Структура CRYPT_KDF_TREE_DIVERSBLOB_HEADER описывает блоб типа KDF_TREE_DIVERSBLOB для процедуры диверсификации КриптоПро CSP, предусматривающей возможность выработки нескольких ключей.
_CRYPT_KDF_TREE_DIVERS_INFO | Структура CRYPT_KDF_TREE_DIVERS_INFO содержит параметры R, L, длины Seed и Label для процедуры диверсификации КриптоПро CSP, предусматривающей возможность выработки нескольких ключей.
_CRYPT_KDF_TREE_DIVERSBLOB | Структура CRYPT_KDF_TREE_DIVERSBLOB описывает блоб типа KDF_TREE_DIVERSBLOB для процедуры диверсификации КриптоПро CSP, предусматривающей возможность выработки нескольких ключей.
_CRYPT_PIN_NK_PARAM | Структура передачи информации для слияния частей контейнера.
_CRYPT_PIN_PARAM | Структура передачи информации для: 1) смены пароля контейнера, 2) указания способа доступа к контейнеру (имя, handle, пароль), на ключе которого зашифровано содержимое другого контейнера.
_CRYPT_NK_INFO_PARAM | Структура получения информации о контейнере разделенного на части.
_CRYPT_PASSWD_INFO_PARAM | Структура для получения информации о пароле на контейнер.
_CRYPT_PIN_INFO_SOURCE | Структура для получения информации о пароле на контейнер.
_CRYPT_PIN_INFO | Структура для получения информации о пароле на контейнер.
_CRYPT_FKC_EKE_AUTH_INFO_PARAM | Структура получения информации о пароле контейнера для аутентификации по EKE.
_CRYPT_FKC_PIN_INFO_SOURCE | Структура для получения информации о пароле на контейнер.
_CRYPT_FKC_PIN_INFO | Структура для получения информации о пароле на контейнер.
_CRYPT_FKC_DH_CHECK | Структура для получения статуса проверки открытого ключа. Получает и устанавливает параметр "проверка открытого ключа в операции Диффи-Хеллмана" для провайдеров FKC ( PP_FKC_DH_CHECK ).
_CRYPT_CACHE_SIZE | Структура для получения и установки настроек кэширования контейнеров.
_CRYPT_ENUMREADER_INFO | Блоб с информацией о считывателе, представляющий собой сериализованную псевдоструктуру.
_CRYPT_ENUMREADER_INFO_MEDIA | Блоб с информацией о считывателе, представляющий собой сериализованную псевдоструктуру.
_CRYPT_HASH_BLOB_EX | Структура передачи информации для получения и установки разделённого значения параметра R для ЭЦП на базе функционального ключевого носителя.
_CRYPT_KEY_PERIOD | Структура для задания периодов действия ключей во вновь создаваемом контейнере.
_TOKEN_VERIFYDATA | Структура передачи информации функции хэширования по алгоритму CALG_EKEVERIFY_HASH.
_CONTAINER_EXTENSION | Блоб с сериализованной псевдоструктурой с расширением.
_VTABLEPROVSTRUC | Структура VTABLEPROVSTRUC содержит указатели на callback функции, которые могут быть использованы функциями криптопровайдера (CSP).
Определения типов | Описание
CPC_Kernel_Fpu_Begin_Callback | Описание функции захвата FPU в режиме ядра ОС.
CPC_Kernel_Fpu_End_Callback | Описание функции освобождения FPU в режиме ядра ОС.
Макросы | Описание
CRYPT_MODE_CBCSTRICT | Режим блочного шифрования с обратной связью на базе ГОСТ 28147-89, шифр-текст блока всегда является IV для следующего.
CRYPT_MODE_CBCRFC4357 | Режим блочного шифрования с обратной связью на базе ГОСТ 28147-89, согласно RFC 4357.
CRYPT_MODE_CNT | Режим шифрования "гаммированием" по ГОСТ 28147-89.
CRYPT_MODE_CTR | Режим шифрования "гаммирование" по ГОСТ Р 34.13-2015.
SECRET_KEY_LEN | Длина в байтах ключа ГОСТ 28147-89 и закрытых ключей ГОСТ Р 34.10-94 и ГОСТ Р 34.10-2001.
G28147_KEYLEN | Длина в байтах ключа ГОСТ 28147-89.
EXPORT_IMIT_SIZE | Длина в байтах имитовставки при импорте/экспорте.
CHECK_VALUE_SIZE | Длина в байтах контрольной величины ключа при импорте и получении параметра ключа.
SEANCE_VECTOR_LEN | Длина в байтах вектора инициализации алгоритма.
MAX_CONTAINER_NAME_LEN | Максимальная разрешённая длина имени ключевого контейнера.
GR3410_1_MAGIC | Признак ключей ГОСТ Р 34.10-94 и ГОСТ Р 34.10-2001.
G28147_MAGIC | Признак ключей ГОСТ 28147-89 и мастер ключей TLS.
DIVERS_MAGIC | Признак ключевого блоба функции диверсификации ключа.
KEXP15_MAGIC | Признак ключевого блоба алгоритма KExp15.
BLOB_VERSION | Текущее значение версии ключевого блоба.
KEXP15_BLOB_VERSION | Текущее значение версии ключевого блоба KExp15.
CP_CRYPT_PUBLICKEY_FROM_CERT | Флаг, устанавливающий признак получения открытого ключа из сертификата.
VER_TYPE_DEBUG | Отладочная версия дистрибутива.
VER_TYPE_RELEASE | Релизная версия дистрибутива.
VER_ARCH_IA32 | Архитектура IA32.
VER_ARCH_IA64 | Архитектура IA64.
VER_ARCH_SPARC32 | Архитектура Sparc32.
VER_ARCH_SPARC64 | Архитектура Sparc64.
VER_ARCH_AMD64 | Архитектура AMD64.
VER_ARCH_ARM | Архитектура ARM.
VER_ARCH_PPC32 | Архитектура PowerPC32.
VER_ARCH_PPC64 | Архитектура PowerPC64.
VER_ARCH_ARM64 | Архитектура ARM64.
VER_ARCH_MIPS32 | Архитектура MIPS32.
VER_OS_WINDOWS | ОС Windows.
VER_OS_SOLARIS | ОС Solaris.
VER_OS_FREEBSD | ОС FreeBSD.
VER_OS_LINUX | ОС Linux.
VER_OS_AIX | ОС AIX.
VER_OS_DARWIN | ОС Mac OS X.
VER_OS_IOS | Apple iOS.
VER_OS_ANDROID | ANDROID OS.
VER_OS_BITVISOR | BITVISOR_OS.
VER_OS_UCLIBC | UCLIBC runtime.
Перечисления | Описание
_CRYPT_FKC_DH_CHECK_VAL | Значения параметра "проверка открытого ключа в операции Диффи-Хеллмана". При установке параметра передается переменной типа DWORD.


Переключатели кода

Значения переключателей кода на более быстрый (с использованием SSE2).

При использовании в функции CPGetProvParam (PP_FAST_CODE_FLAGS), в параметре pbData возвращаются флаги, определяющие набор проверенных на включённый код функций. Указание, какие функции проверять на включённый код, передаётся во флагах dwFlags.

Если применён флаг CRYPT_FAST_CODE_GET_SETFN, при выходе CSP_FAST_CODE_GET_SETFN будет установлен в 1, если провайдер может использовать быстрый код, и 0 - иначе. Если установлен флаг CRYPT_FAST_CODE_ALL_FUNCTIONS, будут проверяться все функции, и на выходе будут установлены все флаги CSP_FAST_CODE_E_ECB , CSP_FAST_CODE_E_CBC , CSP_FAST_CODE_E_CNT , CSP_FAST_CODE_E_CFB , CSP_FAST_CODE_E_OFB , CSP_FAST_CODE_E_CTR , CSP_FAST_CODE_D_ECB , CSP_FAST_CODE_D_CBC , CSP_FAST_CODE_D_CNT , CSP_FAST_CODE_D_CFB , CSP_FAST_CODE_D_OFB , CSP_FAST_CODE_D_CTR , CSP_FAST_CODE_MD_ECB , CSP_FAST_CODE_GR3411SP , CSP_FAST_CODE_GR3411H , CSP_FAST_CODE_GR3411HV , CSP_FAST_CODE_HASH , CSP_FAST_CODE_HASH_2012 , CSP_FAST_CODE_HASH_2012HV , CSP_FAST_CODE_IMIT , CSP_FAST_CODE_IMIT_2015 , CSP_FAST_CODE_MULT , в 1, если соответствующая функция использует быстрый код, и 0 - иначе. В режиме пользователя следует вместо флага CRYPT_FAST_CODE_ALL_FUNCTIONS использовать CRYPT_FAST_CODE_ALL_USER_FUNCTIONS, а в режиме ядра ОС - CRYPT_FAST_CODE_ALL_KERNEL_FUNCTIONS. На выходе флаг CSP_FAST_CODE_GET_FN установлен в 1, если быстрый код работает во всех выбранных функциях, и 0 если хотя бы одна из выбранных функций не сработала. Поведение не выбранных флагов не определено.

Макросы | Описание
CSP_FAST_CODE_GET_FN | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется для определения полноты набора установленных быстрых функций.
CSP_FAST_CODE_GET_SETFN | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется для определения, может ли провайдер исполнять быстрый код на данной машине.
CSP_FAST_CODE_E_ECB | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции зашифрования по ECB Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_E_CBC | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции зашифрования по CBC Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_E_CNT | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции зашифрования по CNT Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_D_CNT | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции расшифрования по CNT Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_E_CFB | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции зашифрования по CFB Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_D_ECB | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции расшифрования по ECB Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_D_CBC | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции расшифрования по CBC Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_D_CFB | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции расшифрования по CFB Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_MD_ECB | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции маскирования ключа Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_GR3411SP | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в упрощенной функции хэширования. Флаг устанавливается только в режиме ядра ОС. Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_GR3411H | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции хэширования. Флаг устанавливается только в режиме ядра ОС. Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_GR3411HV | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции проверки хэша. Флаг устанавливается только в режиме ядра ОС. Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_HASH | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции хэш-преобразования. Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_IMIT | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции выработки имитовставки. Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_MULT | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции умножения. Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_MULT_ATT | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функциях умножения в UNIX-оподобных системах. Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_HASH_2012 | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции хэш-преобразования по ГОСТ Р 34.11-2012. Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_HASH_2012HV | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции проверки хэша по ГОСТ Р 34.11-2012. Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_DISABLE_SSSE3 | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, используется ли SSSE3 код. Выставлен, если код не используется.
CSP_FAST_CODE_DISABLE_AVX | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, используется ли AVX код. Выставлен, если код не используется.
CSP_FAST_CODE_RT_TS | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Признак, что для захвата FPU используется TS-бит (Solaris, Linux).
CSP_FAST_CODE_E_OFB | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции зашифрования по OFB Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_D_OFB | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции расшифрования по OFB Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_E_CTR | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции зашифрования по CTR Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_D_CTR | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции расшифрования по CTR Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_IMIT_2015 | Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции выработки имитовставки по ГОСТ Р 34.13-2015. Равен 1 в случае быстрого кода данной функции, и 0 иначе.
CSP_FAST_CODE_ALL_ENCRYPT | Набор флагов, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Группирует все флаги функций зашифрования.
CSP_FAST_CODE_ALL_DECRYPT | Набор флагов, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Группирует все флаги функций расшифрования.
CSP_FAST_CODE_ALL_HASH | Набор флагов, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Группирует все флаги функций хэширования.
CSP_FAST_CODE_ALL_MULT | Набор флагов, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Группирует все флаги функций умножения.
CSP_FAST_CODE_ALL_CRYPT | Набор флагов, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Группирует все флаги функций шифрования.
CSP_FAST_CODE_ALL_FUNCTIONS | Набор флагов, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Группирует все флаги переключаемых функций криптопровайдера.
CSP_FAST_CODE_ALL_KERNEL_FUNCTIONS | Набор флагов, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Группирует все флаги переключаемых функций криптопровайдера режима ядра ОС.
CSP_FAST_CODE_ALL_USER_FUNCTIONS | Набор флагов, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Группирует все флаги переключаемых функций криптопровайдера пользовательского режима.
CRYPT_FAST_CODE_ALL_KERNEL_FUNCTIONS | Флаг, используемый при вызове CPGetProvParam (PP_FAST_CODE_FLAGS), запращивает вариант кода для всех функций провайдера в режиме ядра ОС.
CRYPT_FAST_CODE_ALL_USER_FUNCTIONS | Флаг, используемый при вызове CPGetProvParam (PP_FAST_CODE_FLAGS), запращивает вариант кода для всех функций провайдера в режиме пользователя.
CRYPT_FAST_CODE_ALL_FUNCTIONS | Флаг, используемый при вызове CPGetProvParam (PP_FAST_CODE_FLAGS), запращивает вариант кода для всех функций провайдера.
CRYPT_FAST_CODE_GET_SETFN | Флаг, используемый при вызове CPGetProvParam (PP_FAST_CODE_FLAGS), запрашивает результат определения процессора.
CSP_OPERATION_CIPHER1 | Возможное значение аргумента op_type функции CPC_Kernel_Fpu_Begin_Callback . Означает, что запрос захвата FPU произошел в функции неспараллеленного шифрования. Также задает значение идентификатора набора функций неспараллеливаемого шифрования, использующих расширение MMX.
CSP_OPERATION_CIPHER2 | Возможное значение аргумента op_type функции CPC_Kernel_Fpu_Begin_Callback . Означает, что запрос захвата FPU произошел в функции спараллеленного шифрования. Также задает значение идентификатора набора функций спараллеленного шифрования, использующих расширение MMX.
CSP_OPERATION_IMIT | Возможное значение аргумента op_type функции CPC_Kernel_Fpu_Begin_Callback . Означает, что запрос захвата FPU произошел в функции выработки имитовставки. Также задает значение идентификатора набора функций выработки имитовставки, использующих расширение MMX.
CSP_OPERATION_HASH | Возможное значение аргумента op_type функции CPC_Kernel_Fpu_Begin_Callback . Означает, что запрос захвата FPU произошел в функции вычисления хэша. В данном случае необходимо сохранять не только регистры ST0 - ST7, но и XMM0 - XMM7. Также задает значение идентификатора набора функций хэшифрования, использующих расширения MMX и SSE2.
CSP_OPERATION_MULT | Битовая маска для включения/выключения кода MMX в функции умножения. Задает значение идентификатора набора функций умножения по модулю P, использующих расширения MMX и SSE2. Применяется только в пользовательском режиме.
CSP_OPERATION_ALL | Битовая маска для включения/выключения кода MMX во всех функциях. Задает значение логической суммы всех идентификаторов наборов функций, использующих MMX и SSE2.
CSP_OPERATION_UNDEF | Битовая маска, означающая неопределенную установку функций. Применяется, если нужно установить набор функций по умолчанию для данного процессора.

См. также

CPGetProvParam (PP_FAST_CODE_FLAGS)


CSP_FAST_CODE_GET_FN

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется для определения полноты набора установленных быстрых функций.
#define CSP_FAST_CODE_GET_FN (1<<28)


CSP_FAST_CODE_GET_SETFN

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется для определения, может ли провайдер исполнять быстрый код на данной машине.
#define CSP_FAST_CODE_GET_SETFN (1<<27)


CSP_FAST_CODE_E_ECB

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции зашифрования по ECB Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_E_ECB (1)


CSP_FAST_CODE_E_CBC

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции зашифрования по CBC Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_E_CBC (1<<1)


CSP_FAST_CODE_E_CNT

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции зашифрования по CNT Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_E_CNT (1<<2)


CSP_FAST_CODE_D_CNT

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции расшифрования по CNT Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_D_CNT (1<<2)


CSP_FAST_CODE_E_CFB

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции зашифрования по CFB Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_E_CFB (1<<3)


CSP_FAST_CODE_D_ECB

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции расшифрования по ECB Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_D_ECB (1<<4)


CSP_FAST_CODE_D_CBC

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции расшифрования по CBC Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_D_CBC (1<<5)


CSP_FAST_CODE_D_CFB

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции расшифрования по CFB Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_D_CFB (1<<6)


CSP_FAST_CODE_MD_ECB

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции маскирования ключа Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_MD_ECB (1<<7)


CSP_FAST_CODE_GR3411SP

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в упрощенной функции хэширования. Флаг устанавливается только в режиме ядра ОС. Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_GR3411SP (1<<8)


CSP_FAST_CODE_GR3411H

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции хэширования. Флаг устанавливается только в режиме ядра ОС. Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_GR3411H (1<<9)


CSP_FAST_CODE_GR3411HV

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции проверки хэша. Флаг устанавливается только в режиме ядра ОС. Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_GR3411HV (1<<10)


CSP_FAST_CODE_HASH

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции хэш-преобразования. Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_HASH (1<<11)


CSP_FAST_CODE_IMIT

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции выработки имитовставки. Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_IMIT (1<<12)


CSP_FAST_CODE_MULT

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции умножения. Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_MULT (1<<13)


CSP_FAST_CODE_MULT_ATT

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функциях умножения в UNIX-оподобных системах. Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_MULT_ATT (1<<13)


CSP_FAST_CODE_HASH_2012

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции хэш-преобразования по ГОСТ Р 34.11-2012. Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_HASH_2012 (1<<14)


CSP_FAST_CODE_HASH_2012HV

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции проверки хэша по ГОСТ Р 34.11-2012. Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_HASH_2012HV (1<<15)


CSP_FAST_CODE_DISABLE_SSSE3

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, используется ли SSSE3 код. Выставлен, если код не используется.
#define CSP_FAST_CODE_DISABLE_SSSE3 (1<<16)


CSP_FAST_CODE_DISABLE_AVX

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, используется ли AVX код. Выставлен, если код не используется.
#define CSP_FAST_CODE_DISABLE_AVX (1<<17)


CSP_FAST_CODE_RT_TS

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Признак, что для захвата FPU используется TS-бит (Solaris, Linux).
#define CSP_FAST_CODE_RT_TS (1<<18)


CSP_FAST_CODE_E_OFB

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции зашифрования по OFB Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_E_OFB (1<<19)


CSP_FAST_CODE_D_OFB

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции расшифрования по OFB Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_D_OFB (1<<19)


CSP_FAST_CODE_E_CTR

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции зашифрования по CTR Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_E_CTR (1<<20)


CSP_FAST_CODE_D_CTR

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции расшифрования по CTR Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_D_CTR (1<<20)


CSP_FAST_CODE_IMIT_2015

Флаг, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Используется как флаг для проверки, какой код применяется в функции выработки имитовставки по ГОСТ Р 34.13-2015. Равен 1 в случае быстрого кода данной функции, и 0 иначе.
#define CSP_FAST_CODE_IMIT_2015 (1<<21)


CSP_FAST_CODE_ALL_ENCRYPT

Набор флагов, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Группирует все флаги функций зашифрования.
#define CSP_FAST_CODE_ALL_ENCRYPT (CSP_FAST_CODE_E_ECB|CSP_FAST_CODE_E_CBC|CSP_FAST_CODE_E_CNT|CSP_FAST_CODE_E_CFB|CSP_FAST_CODE_E_OFB|CSP_FAST_CODE_E_CTR)


CSP_FAST_CODE_ALL_DECRYPT

Набор флагов, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Группирует все флаги функций расшифрования.
#define CSP_FAST_CODE_ALL_DECRYPT (CSP_FAST_CODE_D_ECB|CSP_FAST_CODE_D_CBC|CSP_FAST_CODE_D_CNT|CSP_FAST_CODE_D_CFB|CSP_FAST_CODE_D_OFB|CSP_FAST_CODE_D_CTR)


CSP_FAST_CODE_ALL_HASH

Набор флагов, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Группирует все флаги функций хэширования.
#define CSP_FAST_CODE_ALL_HASH (CSP_FAST_CODE_HASH|CSP_FAST_CODE_GR3411SP|CSP_FAST_CODE_GR3411H|CSP_FAST_CODE_GR3411HV|CSP_FAST_CODE_HASH_2012|CSP_FAST_CODE_HASH_2012HV)


CSP_FAST_CODE_ALL_MULT

Набор флагов, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Группирует все флаги функций умножения.
#define CSP_FAST_CODE_ALL_MULT (CSP_FAST_CODE_MULT|CSP_FAST_CODE_MULT_ATT)


CSP_FAST_CODE_ALL_CRYPT

Набор флагов, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Группирует все флаги функций шифрования.
#define CSP_FAST_CODE_ALL_CRYPT (CSP_FAST_CODE_ALL_ENCRYPT|CSP_FAST_CODE_ALL_DECRYPT|CSP_FAST_CODE_MD_ECB|CSP_FAST_CODE_IMIT|CSP_FAST_CODE_IMIT_2015)


CSP_FAST_CODE_ALL_FUNCTIONS

Набор флагов, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Группирует все флаги переключаемых функций криптопровайдера.
#define CSP_FAST_CODE_ALL_FUNCTIONS (CSP_FAST_CODE_ALL_CRYPT|CSP_FAST_CODE_ALL_HASH|CSP_FAST_CODE_ALL_MULT)


CSP_FAST_CODE_ALL_KERNEL_FUNCTIONS

Набор флагов, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Группирует все флаги переключаемых функций криптопровайдера режима ядра ОС.
#define CSP_FAST_CODE_ALL_KERNEL_FUNCTIONS (CSP_FAST_CODE_ALL_CRYPT|CSP_FAST_CODE_ALL_HASH)


CSP_FAST_CODE_ALL_USER_FUNCTIONS

Набор флагов, возвращаемый функцией CPGetProvParam (PP_FAST_CODE_FLAGS). Группирует все флаги переключаемых функций криптопровайдера пользовательского режима.
#define CSP_FAST_CODE_ALL_USER_FUNCTIONS (CSP_FAST_CODE_ALL_CRYPT|CSP_FAST_CODE_HASH|CSP_FAST_CODE_HASH_2012|CSP_FAST_CODE_HASH_2012HV|CSP_FAST_CODE_ALL_MULT)


CRYPT_FAST_CODE_ALL_KERNEL_FUNCTIONS

Флаг, используемый при вызове CPGetProvParam (PP_FAST_CODE_FLAGS), запращивает вариант кода для всех функций провайдера в режиме ядра ОС.
#define CRYPT_FAST_CODE_ALL_KERNEL_FUNCTIONS 1


CRYPT_FAST_CODE_ALL_USER_FUNCTIONS

Флаг, используемый при вызове CPGetProvParam (PP_FAST_CODE_FLAGS), запращивает вариант кода для всех функций провайдера в режиме пользователя.
#define CRYPT_FAST_CODE_ALL_USER_FUNCTIONS 2


CRYPT_FAST_CODE_ALL_FUNCTIONS

Флаг, используемый при вызове CPGetProvParam (PP_FAST_CODE_FLAGS), запращивает вариант кода для всех функций провайдера.
#define CRYPT_FAST_CODE_ALL_FUNCTIONS (CRYPT_FAST_CODE_ALL_KERNEL_FUNCTIONS|CRYPT_FAST_CODE_ALL_USER_FUNCTIONS)


CRYPT_FAST_CODE_GET_SETFN

Флаг, используемый при вызове CPGetProvParam (PP_FAST_CODE_FLAGS), запрашивает результат определения процессора.
#define CRYPT_FAST_CODE_GET_SETFN 8


CSP_OPERATION_CIPHER1

Возможное значение аргумента op_type функции CPC_Kernel_Fpu_Begin_Callback . Означает, что запрос захвата FPU произошел в функции неспараллеленного шифрования. Также задает значение идентификатора набора функций неспараллеливаемого шифрования, использующих расширение MMX.
#define CSP_OPERATION_CIPHER1 (CSP_FAST_CODE_E_CFB | CSP_FAST_CODE_E_CBC)


CSP_OPERATION_CIPHER2

Возможное значение аргумента op_type функции CPC_Kernel_Fpu_Begin_Callback . Означает, что запрос захвата FPU произошел в функции спараллеленного шифрования. Также задает значение идентификатора набора функций спараллеленного шифрования, использующих расширение MMX.
#define CSP_OPERATION_CIPHER2 (CSP_FAST_CODE_E_ECB | CSP_FAST_CODE_E_CNT | CSP_FAST_CODE_E_OFB | CSP_FAST_CODE_E_CTR | CSP_FAST_CODE_D_ECB | CSP_FAST_CODE_D_CBC | CSP_FAST_CODE_D_CNT | CSP_FAST_CODE_D_OFB | CSP_FAST_CODE_D_CTR | CSP_FAST_CODE_D_CFB | CSP_FAST_CODE_MD_ECB)


CSP_OPERATION_IMIT

Возможное значение аргумента op_type функции CPC_Kernel_Fpu_Begin_Callback . Означает, что запрос захвата FPU произошел в функции выработки имитовставки. Также задает значение идентификатора набора функций выработки имитовставки, использующих расширение MMX.
#define CSP_OPERATION_IMIT (CSP_FAST_CODE_IMIT | CSP_FAST_CODE_IMIT_2015)


CSP_OPERATION_HASH

Возможное значение аргумента op_type функции CPC_Kernel_Fpu_Begin_Callback . Означает, что запрос захвата FPU произошел в функции вычисления хэша. В данном случае необходимо сохранять не только регистры ST0 - ST7, но и XMM0 - XMM7. Также задает значение идентификатора набора функций хэшифрования, использующих расширения MMX и SSE2.
#define CSP_OPERATION_HASH (CSP_FAST_CODE_ALL_HASH)


CSP_OPERATION_MULT

Битовая маска для включения/выключения кода MMX в функции умножения. Задает значение идентификатора набора функций умножения по модулю P, использующих расширения MMX и SSE2. Применяется только в пользовательском режиме.
#define CSP_OPERATION_MULT (CSP_FAST_CODE_ALL_MULT)


CSP_OPERATION_ALL

Битовая маска для включения/выключения кода MMX во всех функциях. Задает значение логической суммы всех идентификаторов наборов функций, использующих MMX и SSE2.
#define CSP_OPERATION_ALL (CSP_OPERATION_MULT | CSP_OPERATION_HASH | CSP_OPERATION_IMIT | CSP_OPERATION_CIPHER2 | CSP_OPERATION_CIPHER1)


CSP_OPERATION_UNDEF

Битовая маска, означающая неопределенную установку функций. Применяется, если нужно установить набор функций по умолчанию для данного процессора.
#define CSP_OPERATION_UNDEF (0xFFFFFFFF)


Шифрование и хэширование пакета

Пакет - неделимый фрагмент данных, подаваемых на функции шифрования CPEncrypt(), CPCEncrypt(),CPDecrypt(), CPCDecrypt(). Пакет состоит из полей:

Поле | Описание
Предзаголовок пакета (DIVERSBLOB) | Опциональное поле, содержащее блоб диверсификации ключа шифрования и хеширования по алгоритму CALG_PRO_DIVERS. Признак обработки поля - установленный флаг CP_CHP_STARTMIX.
Заголовок пакета (HEADER) | Опциональное поле длины не более 255 байт. Не шифруется, хэшируется хеш-функцией hHash.
Вектор инициализации (IV) | Опциональное поле, содержащее вектор инициализации шифрования пакета. Не шифруется, хэшируется опционально.
Тело пакета (PAYLOAD) | Обязательное поле, шифруется и хэшируется.
Трейлер (TRAILER) | Опциональное поле длины не более 254 байт. Не шифруется, хэшируется хеш-функцией hHash.
Знечение функции хэширования пакета (HASH) | Опциональное поле, может быть зашифровано.

При шифровании пакетов поддерживаются режимы шифрования: CRYPT_MODE_CNT, CRYPT_MODE_CFB, CRYPT_MODE_CBCSTRICT. Во всех режимах шифрования могут быть использованы флаги: CRYPT_PROMIX_MODE, CRYPT_SIMPLEMIX_MODE.

В пакетном режиме шифрования длина пакетов остаётся неизменной.

В режиме CBC общая длина шифруемых данных должна быть кратна 8, также должна быть кратной 8 длина каждого шифруемого элемента IOVEC, в противном случае возвращается ошибка NTE_BAD_DATA. Пакеты обрабатываются с сохранением размера полей, паддинг в режиме CBC игнорируется.

Флаги CP_CHP_IV_RANDOM, CP_CHP_IV_USER, CP_CHP_HASH_PACKET предназначены для обработки пакетов в потоках с возможным нарушением порядка следования пакетов, с возможной потерей пакетов.

Флаги CP_CHP_IV_CHAIN, CP_CHP_HASH_CHAIN, CP_CHP_HASH_NONE предназначены для обработки пакетов в потоках, гарантирующих доставку всех пакетов в неизменной последовательности.

В следующей таблице приведены условия использовантя режимов ширования пакетов:

Значение флагов | Условия и ограничения режима
CRYPT_SIMPLEMIX_MODE совместно с CP_CHP_IV_RANDOM, CRYPT_SIMPLEMIX_MODE совместно с CP_CHP_IV_USER | Обработка пакетов может выполняться с установленным флагом Final=FALSE. Объём данных, обрабатываемых на одном ключе, ограничен 4М.
CRYPT_PROMIX_MODE совместно с CP_CHP_IV_RANDOM, CRYPT_PROMIX_MODE совместно с CP_CHP_IV_USER | Обработка пакетов должна выполняться с установленным флагом Final=TRUE. Объём данных, обрабатываемых на одном ключе, ограничен 4М либо числом пакетов < 4096.
CRYPT_SIMPLEMIX_MODE совместно с CP_CHP_IV_CHAIN | Обработка пакета с флагом Final=TRUE означает завершение обработки цепочки пакетов. Обработка пакета с флагом Final=FALSE означает продолжение обработки цепочки пакетов. На одном ключе последовательно может быть обработано несколько цепочек пакетов. Объём данных, обрабатываемых на одном ключе, ограничен 4М.
CRYPT_PROMIX_MODE совместно с CP_CHP_IV_CHAIN | Обработка пакета с флагом Final=TRUE означает завершение обработки цепочки пакетов. Обработка пакета с флагом Final=FALSE означает продолжение обработки цепочки пакетов. На одном ключе может обрабатываться цепочка длины не более 128000М. Количество цепочек ограничено 4096.

Во всех режимах объект функции хэширования после завершения обработки пакета подготовлен для обработки следующего пакета. При этом, в случае CP_CHP_HASH_CHAIN и CP_CHP_HASH_NONE объект открыт для продолжения хэширования потока, в случае CP_CHP_HASH_PACKET объект инициализирован.

При расшифровании пакета в случае его искажения в канале, приводящего к несовпадению значения HASH, передаваемого в составе пакета, с вновь рассчитанным значением, функция CPDecrypt() возвращают ошибку (FALSE), функции CPCDecrypt() и GetLastError() возвращают NTE_BAD_HASH, объект функции хэширования функциями CPDecrypt(), CPCDecrypt() не инициализируется. В этом случае приложение может получить рассчитанное значение HASH вызовом CPGetHashParam() и должно принять решение о завершении обрабатываемого потока (например: поток, обрабатываемый с флагом CP_CHP_HASH_CHAIN, должен быть закрыт; поток, обрабатываемый с флагом CP_CHP_HASH_PACKET может быть продолжен). В случае продолжения обработки потока приложение должно открыть (создать новый) объект функции хэширования.

Во входных параметрах функций шифрования и хэширования пакет может быть представлен как буфером, определяемым указателем pbData и длиной cbData, так и вектором IOVEC ввода/вывода, определяемым указателем pbData на вершину массива структур CSP_iovec и числом элементов массива cbData. Режим использования векторной формы представления ввода/вывода определяется флагом CP_CRYPT_DATA_IOVEC, в настоящей версии СКЗИ режим CP_CRYPT_DATA_IOVEC является подрежимом пакетной обработки.

В режиме пакетной обработки возможно получение ключа шифрования и имитозащиты пакета диверсификацией базовых ключей, ассоциированных с hKey и hHash. Диверсификация осуществляется по алгоритму CALG_PRO_DIVERS с использованием даных CRYPT_DIVERSBLOB, размещённых в предзаголовке пакета. Если используется представление данных в форме вектора ввода-вывода, блоб диверсификации должен передаваться в первой координате вектора целиком. Признаком использования диверсификации ключей является установленный флаг CP_CHP_STARTMIX. Диверсифицированное значение ключей сохраняется для использования для обработки последующих пакетов. Диверсификация ключей не приводит к изменению значений базовых ключей.

В режиме пакетной обработки возможна SIMD параллельная обработка до 16 пакетов при использовании аппаратной платформы, поддерживающей расширения SSSE3, AVX. Все пакеты обрабатываются на ключах с одним значением для шифрования и с обним значением для функции хешироваия. Пакеты должны быть упакованы в массиве структур CSP_Multipacket. Признаком использования мультипакетной обработки является установленный флаг CP_CHP_MULTIPACKET. Пакеты могут быть представлены как линейным буфером, так и вектором IOVEC ввода/вывода. Требуется, чтобы все пакеты были однотипными, тип пакетов определяется флагом CP_CRYPT_DATA_IOVEC. В мультипакетном режиме использование предварительной диверсификации ключа, определяемой флагом CP_CHP_STARTMIX, не допускается. См. Мультипакетная обработка .

Флаг CP_CRYPT_NOKEYWLOCK используется для организации шифрования\расшифрования пакетов в многопоточном режиме, при этом ключ шифрования\расшифрования блокируется только на чтение. Для обеспечения данного режима работы необходимо заранее создать специальный объект HCRYPTMODULE с помощью функции CPCGetProvParam() с флагом PP_CREATE_THREAD_CSP; данный объект в дальнейшем следует передавать функциям CPCEncrypt() и CPCDecrypt() в качестве первого параметра.

Использование флага CP_CRYPT_NOKEYWLOCK разрешается только совместно с флагом CP_CRYPT_HASH_PACKET, при значении параметра Final == TRUE; использование флага при шифровании\расшифровании на ключе с режимом преобразования (KP_MIXMODE), отличным от CRYPT_SIMPLEMIX_MODE, а также совместно с флагом CP_CHP_IV_CHAIN не допускается.

Пример

 CPCGetProvParam(hCSP, hProv, PP_CREATE_THREAD_CSP, NULL, &dwThreadCSPData, 0);

 pbThreadCSPData = (BYTE*)malloc(dwThreadCSPData);

 CPCGetProvParam(hCSP, hProv, PP_CREATE_THREAD_CSP, pbThreadCSPData, &dwThreadCSPData, 0);

 hThreadCSP = (HCRYPTMODULE)pbThreadCSPData;

 CPCEncrypt(hThreadCSP, hProv, hKey, hHash, TRUE, CP_CHP(CP_CHP_HASH_ENCRYPT | CP_CHP_IV_RANDOM | CP_CHP_STARTMIX |
 CP_CHP_HASH_PACKET | CP_CRYPT_NOKEYWLOCK, HEADER_BYTE_SIZE, TRAILER_BYTE_SIZE, HASH_DWORD_SIZE), pbThreadPacketData, &cbThreadPacketData, cbThreadPacketData);

Умолчания:

1. В случае hHash=0, значение функции хэширования не рассчитывается.

2. Представление данных в виде IOVEC является производным от представления, определяемого флагами. Имеется ввиду, что IOVEC представляет данные, а описание структуры данных содержится во флагах.

3. Максимальное количество элементов IOVEC зависит от реализации. Любая реализация должна предоставлять возможность использовать 16 элементов IOVEC.

4. Поле длины элемента IOVEC >= 0.

Структура пакета и порядок обработки полей пакета определяются значениями флагов параметра dwFlags, объединяемыми операцией OR; значения флагов зависимы, не все сочетания значений полей допустимы. Для формирования флагов рекомендуется использовать макрос CP_CHP().

Макросы | Описание
CP_CRYPT_HASH_PACKET | Флаг - признак пакетной обработки данных, должен быть установлен, если используется обработка пакета, в противном случае dwFlags должен быть равен нулю, что соответствует обработке простого потока данных.
CP_CHP_HASH_ENCRYPT | Флаг определяет порядок обработки данных пакета - хэширование (имитозащита) затем шифрование.
CP_CHP_ENCRYPT_HASH | Флаг определяет порядок обработки данных пакета - шифрование затем хэширование (имитозащита).
CP_CHP_MULTIPACKET | Флаг - признак мультипакетного режима работы. Параметр pbData должен указывать на массив структур CSP_MultiPacket_ENC/CSP_Multipacket_DEC, в параметре cbData/reserved передаётся число структур в массиве (не должно превышать 16). В каждой из структур CSP_MultiPacket_ENC/CSP_Multipacket_DEC до вызова CPEncrypt()/CPDecrypt() соответственно в поле dwResult должно быть записано значение 1. В случае ошибок, связанных с проверкой значений имитовставки одного или нескольких пакетов (ошибка NTE_BAD_HASH), после выхода из функции в поле dwResult будет 0 только у тех пакетов, обработка которых завершилась с успешной проверкой значения имитовставки (значения функции хеширования).
CP_CRYPT_NOKEYWLOCK | Флаг - признак работы с блокировкой ключа только на чтение. Ситуации, при которой блокировка на чтение невозможна, сопоставляется ошибка NTE_BAD_FLAGS.
CP_CHP_IV_HEADER | Флаг хэширования вектора инициализации (IV). Если установлен, IV следует за заголовком пакета и хэшируется. Если не установлен, IV ,если присутствует в пакете, следует за заголовком пакета, но не хэшируется.
CP_CHP_STARTMIX | Флаг диверсификации ключа шифрования и хеширования по алгоритму CALG_PRO_DIVERS. Если используется представление данных в форме пакета, блоб диверсификации должен передаваться в составе пакета в его начале. Если используется представление данных в форме вектора ввода-вывода, блоб диверсификации должен передаваться в первой координате вектора целиком. При обработке мультипакета (флаг CP_CHP_MULTIPACKET установлен) блоб диверсификации должен передаваться в составе первого пакета, в этом случае все пакеты мультипакета обрабатваются на диверсифицированных ключах шифрования и имитозащиты.
CP_CHP_IV_MASK | Маска управления IV. Представляет собой поле из 2 зависимых бит. Нулевое значение поля соответствует CP_CHP_IV_CHAIN. Ненулевые значения соответствуют CP_CHP_IV_USER, CP_CHP_IV_RANDOM. Может быть установлен только один из флагов CP_CHP_IV_CHAIN, CP_CHP_IV_USER, CP_CHP_IV_RANDOM.
CP_CHP_IV_RANDOM | Если флаг установлен, IV генерируется функцией CPEncrypt(...,CP_CRYPT_HASH_PACKET|CP_CHP_IV_CHAIN...,...) (CPCEncrypt()) и передаётся в пакет. Функция CPDecrypt(...,CP_CRYPT_HASH_PACKET|CP_CHP_IV_CHAIN...,...) (CPCEncrypt()) считывает IV из пакета.
CP_CHP_IV_USER | Если флаг установлен, приложение устанавливает IV в пакет, функции CPEncrypt(...,CP_CRYPT_HASH_PACKET|CP_CHP_IV_CHAIN...,...) (CPCEncrypt()), CPDecrypt(...,CP_CRYPT_HASH_PACKET|CP_CHP_IV_CHAIN...,...) (CPCEncrypt()) считывают IV из пакета.
CP_CHP_IV_CHAIN | Если флаг установлен, функции CPEncrypt(...,CP_CRYPT_HASH_PACKET|CP_CHP_IV_CHAIN...,...) (CPCEncrypt()), CPDecrypt(...,CP_CRYPT_HASH_PACKET|CP_CHP_IV_CHAIN...,...) (CPCDecrypt()) получают IV пакета из контекста ключа.
CP_CHP_HASH_MASK | Маска управления значением хеш-функции пакета. Представляет собой поле из 2 зависимых бит. Нулевое значение поля соответствует CP_CHP_HASH_NONE. Ненулевые значения соответствуют CP_CHP_HASH_CHAIN, CP_CHP_HASH_PACKET. Может быть установлен только один из флагов CP_CHP_HASH_NONE, CP_CHP_HASH_CHAIN, CP_CHP_HASH_PACKET.
CP_CHP_HASH_NONE | Если флаг установлен, функция хэширования расчитывается на весь поток пакетов. В пакет значение хеш-функции не передаётся.
CP_CHP_HASH_CHAIN | Если флаг установлен, функция хэширования рассчитывается на поток пакетов, текущее значение хеш-функции устанавливается в пакет функциями CPEncrypt(...,CP_CRYPT_HASH_PACKET|CP_CHP_HASH_CHAIN...,...) (CPCEncrypt()). Функции CPDecrypt(...,CP_CRYPT_HASH_PACKET|CP_CHP_IV_CHAIN...,...) (CPCDecrypt()) сравнивают рассчитанное значение хеш-функции со значением, полученным из пакета, и в случае несовпадения возвращают ошибку NTE_BAD_HASH.
CP_CHP_HASH_PACKET | Если флаг установлен, функция хэширования рассчитывается на пакет, значение хеш-функции устанавливается в пакет функциями CPEncrypt(...,CP_CRYPT_HASH_PACKET|CP_CHP_HASH_CHAIN...,...) (CPCEncrypt()). Функции CPDecrypt(...,CP_CRYPT_HASH_PACKET|CP_CHP_IV_CHAIN...,...) (CPCDecrypt()) сравнивают рассчитанное значение хеш-функции со значением, полученным из пакета, и в случае несовпадения возвращают ошибку NTE_BAD_HASH.
CP_CHP_HASH_SIZE_MASK | Маска размера значения хеш-функции в двойных словах (4 октета), устанавливаемого в пакет. Возможные значения: 1 (для имитозащиты) от 1 до 8 (ддя хеш-функции по ГОСТ Р34.11-94 и HMAC).
CP_CHP_TRAILER_MASK | Маска размера трейлера в байтах, значения 0 - 254 означают длину трейлера, значение 255 означает: длина трейлера 0, значения хеш-функции в пакете шифруется.
CP_CHP_ENCRYPTED_TRAILER | Размер трейлера в байтах, размещённый в младшем байте для интерпретации как числа.
CP_CHP_HEADER_MASK | Маска размера заголовка в байтах, размер может проинимать значения 0 - 255.
CP_CHP | Макрос для формирования параметра dwFlags (флагов) функций CPEncrypt() и CPDecrypt().

См. также

CPEncrypt (CP_CRYPT_HASH_PACKET) ,CPDecrypt (CP_CRYPT_HASH_PACKET) ,CP_CHP()


CP_CRYPT_HASH_PACKET

Флаг - признак пакетной обработки данных, должен быть установлен, если используется обработка пакета, в противном случае dwFlags должен быть равен нулю, что соответствует обработке простого потока данных.
#define CP_CRYPT_HASH_PACKET (0x80)


CP_CHP_HASH_ENCRYPT

Флаг определяет порядок обработки данных пакета - хэширование (имитозащита) затем шифрование.
#define CP_CHP_HASH_ENCRYPT (0x00)


CP_CHP_ENCRYPT_HASH

Флаг определяет порядок обработки данных пакета - шифрование затем хэширование (имитозащита).
#define CP_CHP_ENCRYPT_HASH (0x10)


CP_CHP_MULTIPACKET

Флаг - признак мультипакетного режима работы. Параметр pbData должен указывать на массив структур CSP_MultiPacket_ENC/CSP_Multipacket_DEC, в параметре cbData/reserved передаётся число структур в массиве (не должно превышать 16). В каждой из структур CSP_MultiPacket_ENC/CSP_Multipacket_DEC до вызова CPEncrypt()/CPDecrypt() соответственно в поле dwResult должно быть записано значение 1. В случае ошибок, связанных с проверкой значений имитовставки одного или нескольких пакетов (ошибка NTE_BAD_HASH), после выхода из функции в поле dwResult будет 0 только у тех пакетов, обработка которых завершилась с успешной проверкой значения имитовставки (значения функции хеширования).
#define CP_CHP_MULTIPACKET (0x20)


CP_CRYPT_NOKEYWLOCK

Флаг - признак работы с блокировкой ключа только на чтение. Ситуации, при которой блокировка на чтение невозможна, сопоставляется ошибка NTE_BAD_FLAGS.
#define CP_CRYPT_NOKEYWLOCK (0x40)


CP_CHP_IV_HEADER

Флаг хэширования вектора инициализации (IV). Если установлен, IV следует за заголовком пакета и хэшируется. Если не установлен, IV ,если присутствует в пакете, следует за заголовком пакета, но не хэшируется.
#define CP_CHP_IV_HEADER (0x08)


CP_CHP_STARTMIX

Флаг диверсификации ключа шифрования и хеширования по алгоритму CALG_PRO_DIVERS. Если используется представление данных в форме пакета, блоб диверсификации должен передаваться в составе пакета в его начале. Если используется представление данных в форме вектора ввода-вывода, блоб диверсификации должен передаваться в первой координате вектора целиком. При обработке мультипакета (флаг CP_CHP_MULTIPACKET установлен) блоб диверсификации должен передаваться в составе первого пакета, в этом случае все пакеты мультипакета обрабатваются на диверсифицированных ключах шифрования и имитозащиты.
#define CP_CHP_STARTMIX (0x04)


CP_CHP_IV_MASK

Маска управления IV. Представляет собой поле из 2 зависимых бит. Нулевое значение поля соответствует CP_CHP_IV_CHAIN. Ненулевые значения соответствуют CP_CHP_IV_USER, CP_CHP_IV_RANDOM. Может быть установлен только один из флагов CP_CHP_IV_CHAIN, CP_CHP_IV_USER, CP_CHP_IV_RANDOM.
#define CP_CHP_IV_MASK (0x300)


CP_CHP_IV_RANDOM

Если флаг установлен, IV генерируется функцией CPEncrypt(...,CP_CRYPT_HASH_PACKET|CP_CHP_IV_CHAIN...,...) (CPCEncrypt()) и передаётся в пакет. Функция CPDecrypt(...,CP_CRYPT_HASH_PACKET|CP_CHP_IV_CHAIN...,...) (CPCEncrypt()) считывает IV из пакета.
#define CP_CHP_IV_RANDOM (0x100)


CP_CHP_IV_USER

Если флаг установлен, приложение устанавливает IV в пакет, функции CPEncrypt(...,CP_CRYPT_HASH_PACKET|CP_CHP_IV_CHAIN...,...) (CPCEncrypt()), CPDecrypt(...,CP_CRYPT_HASH_PACKET|CP_CHP_IV_CHAIN...,...) (CPCEncrypt()) считывают IV из пакета.
#define CP_CHP_IV_USER (0x200)


CP_CHP_IV_CHAIN

Если флаг установлен, функции CPEncrypt(...,CP_CRYPT_HASH_PACKET|CP_CHP_IV_CHAIN...,...) (CPCEncrypt()), CPDecrypt(...,CP_CRYPT_HASH_PACKET|CP_CHP_IV_CHAIN...,...) (CPCDecrypt()) получают IV пакета из контекста ключа.
#define CP_CHP_IV_CHAIN (0x000)


CP_CHP_HASH_MASK

Маска управления значением хеш-функции пакета. Представляет собой поле из 2 зависимых бит. Нулевое значение поля соответствует CP_CHP_HASH_NONE. Ненулевые значения соответствуют CP_CHP_HASH_CHAIN, CP_CHP_HASH_PACKET. Может быть установлен только один из флагов CP_CHP_HASH_NONE, CP_CHP_HASH_CHAIN, CP_CHP_HASH_PACKET.
#define CP_CHP_HASH_MASK (0xC00)


CP_CHP_HASH_NONE

Если флаг установлен, функция хэширования расчитывается на весь поток пакетов. В пакет значение хеш-функции не передаётся.
#define CP_CHP_HASH_NONE (0x000)


CP_CHP_HASH_CHAIN

Если флаг установлен, функция хэширования рассчитывается на поток пакетов, текущее значение хеш-функции устанавливается в пакет функциями CPEncrypt(...,CP_CRYPT_HASH_PACKET|CP_CHP_HASH_CHAIN...,...) (CPCEncrypt()). Функции CPDecrypt(...,CP_CRYPT_HASH_PACKET|CP_CHP_IV_CHAIN...,...) (CPCDecrypt()) сравнивают рассчитанное значение хеш-функции со значением, полученным из пакета, и в случае несовпадения возвращают ошибку NTE_BAD_HASH.
#define CP_CHP_HASH_CHAIN (0x400)


CP_CHP_HASH_PACKET

Если флаг установлен, функция хэширования рассчитывается на пакет, значение хеш-функции устанавливается в пакет функциями CPEncrypt(...,CP_CRYPT_HASH_PACKET|CP_CHP_HASH_CHAIN...,...) (CPCEncrypt()). Функции CPDecrypt(...,CP_CRYPT_HASH_PACKET|CP_CHP_IV_CHAIN...,...) (CPCDecrypt()) сравнивают рассчитанное значение хеш-функции со значением, полученным из пакета, и в случае несовпадения возвращают ошибку NTE_BAD_HASH.
#define CP_CHP_HASH_PACKET (0x800)


CP_CHP_HASH_SIZE_MASK

Маска размера значения хеш-функции в двойных словах (4 октета), устанавливаемого в пакет. Возможные значения: 1 (для имитозащиты) от 1 до 8 (ддя хеш-функции по ГОСТ Р34.11-94 и HMAC).
#define CP_CHP_HASH_SIZE_MASK (0xF000)


CP_CHP_TRAILER_MASK

Маска размера трейлера в байтах, значения 0 - 254 означают длину трейлера, значение 255 означает: длина трейлера 0, значения хеш-функции в пакете шифруется.
#define CP_CHP_TRAILER_MASK (0xFF0000)


CP_CHP_ENCRYPTED_TRAILER

Размер трейлера в байтах, размещённый в младшем байте для интерпретации как числа.
#define CP_CHP_ENCRYPTED_TRAILER (CP_CHP_TRAILER_MASK>>CP_CHP_TRAILER_SHIFT)


CP_CHP_HEADER_MASK

Маска размера заголовка в байтах, размер может проинимать значения 0 - 255.
#define CP_CHP_HEADER_MASK (0xFF000000)


CP_CHP

Макрос для формирования параметра dwFlags (флагов) функций CPEncrypt() и CPDecrypt().

Флаги (dwFlags) формируются на основе параметров пакета:

  • флагов порядка вычисления хэш-функции и выработки синхропосылки;
  • размера заголовка;
  • размера "хвоста";
  • размера значения хэш-функции.

#define CP_CHP(Flags, HeaderByteSize, TrailerByteSize, HashDWordSize) (\
            (Flags)|CP_CRYPT_HASH_PACKET|\
            (((HeaderByteSize)<<CP_CHP_HEADER_SHIFT)&CP_CHP_HEADER_MASK)|\
            (((TrailerByteSize)<<CP_CHP_TRAILER_SHIFT)&CP_CHP_TRAILER_MASK)|\
            (((HashDWordSize)<<CP_CHP_HASH_SIZE_SHIFT)&CP_CHP_HASH_SIZE_MASK)\
        )


Вспомогательные макросы описания структуры пакета

В макросах приняты обозначения параметров:

  • параметр f сответствует dwFlags;
  • параметр d сответствует указателю на буфер, содержащий пакет;
  • параметр l сответствует длине пакета.

Макросы | Описание
CP_CHP_HASH_SIZE_SHIFT | Сдвиг поля для маски CP_CHP_HASH_SIZE_MASK.
CP_CHP_TRAILER_SHIFT | Сдвиг поля для маски CP_CHP_TRAILER_MASK.
CP_CHP_HEADER_SHIFT | Сдвиг поля для маски CP_CHP_HEADER_MASK.
CP_CHP_IV_SIZE | Размер поля IV в пакете.
_CP_CHP_ADD_ |
_CP_CHP_SUB_ |
_CP_CHP_SAFE_CHECK_ |
CP_CHP_IV_DATA | Указатель на поле IV в пакете.
CP_CHP_HEADER_DATA | Указатель на поле заголовка в пакете, если заголовок присутствует.
CP_CHP_PUREHEADER_SIZE | Размер поля заголовка пакета.
CP_CHP_HEADER_SIZE | Размер хэшируемого поля заголовка пакета и поля IV (если IV хэшируется).
CP_CHP_REALHEADER_SIZE | Суммарный размер поля заголовка пакета и поля IV.
CP_CHP_HASH_SIZE | Размер поля значения хеш-функции.
CP_CHP_HASH_DATA | Указатель на поле значения хеш-функции в пакете, если поле присутствует.
CP_CHP_HASH_LEN | Длина хэшируемого поля пакета(в случае, когда поле IV хэшируется).
CP_CHP_HASH_LEN_1 | Длина первого хэшируемого поля (в случае, когда поле IV не хэшируется).
CP_CHP_TRAILER_SIZE | Размер поля трейлера.
CP_CHP_TRAILER_DATA | Указатель на поле трейлера в пакете, если поле присутствует.
CP_CHP_PAYLOAD_SIZE | Размер тела пакета.
CP_CHP_CIPHER_SIZE | Размер шифруемого поля пакета.
CP_CHP_CIPHER_DATA | Указатель на шифруемое поле пакета.
CP_CHP_HASH_DATA_2 | Указатель на второе хэшируемое поле пакета (в случае, когда поле IV не хэшируется).
CP_CHP_HASH_LEN_2 | Длина второго хэшируемого поля пакета (в случае, когда поле IV не хэшируется).


CP_CHP_HASH_SIZE_SHIFT

Сдвиг поля для маски CP_CHP_HASH_SIZE_MASK.
#define CP_CHP_HASH_SIZE_SHIFT (12)


CP_CHP_TRAILER_SHIFT

Сдвиг поля для маски CP_CHP_TRAILER_MASK.
#define CP_CHP_TRAILER_SHIFT (16)


CP_CHP_HEADER_SHIFT

Сдвиг поля для маски CP_CHP_HEADER_MASK.
#define CP_CHP_HEADER_SHIFT (24)


CP_CHP_IV_SIZE

Размер поля IV в пакете.
#define CP_CHP_IV_SIZE(f) (((f)&CP_CHP_IV_MASK)?(SEANCE_VECTOR_LEN):(0))


_CP_CHP_ADD_

#define _CP_CHP_ADD_(p, w) ((void *)(((char *)p) + (w)))


_CP_CHP_SUB_

#define _CP_CHP_SUB_(p, w) ((void *)(((char *)p) - (w)))


_CP_CHP_SAFE_CHECK_

#define _CP_CHP_SAFE_CHECK_(d, l, p, w) (NULL != (d) && (size_t)(w) <= (size_t)(l) &&		\
         (void *)(d) <= (void *)(p) &&					\
         _CP_CHP_ADD_((p),(w)) <= _CP_CHP_ADD_((d),(l))		\
        ? (p)							\
        : NULL							\
        )


CP_CHP_IV_DATA

Указатель на поле IV в пакете.
#define CP_CHP_IV_DATA(f, d, l) _CP_CHP_SAFE_CHECK_((d),(l),		\
        _CP_CHP_ADD_((d),					\
            (((f)&CP_CHP_HEADER_MASK)>>CP_CHP_HEADER_SHIFT)),	\
        CP_CHP_IV_SIZE(f)					\
        )


CP_CHP_HEADER_DATA

Указатель на поле заголовка в пакете, если заголовок присутствует.
#define CP_CHP_HEADER_DATA(f, d, l) _CP_CHP_SAFE_CHECK_((d),(l),		\
                    (d), CP_CHP_PUREHEADER_SIZE(f))


CP_CHP_PUREHEADER_SIZE

Размер поля заголовка пакета.
#define CP_CHP_PUREHEADER_SIZE(f) (((f)&CP_CHP_HEADER_MASK)>>CP_CHP_HEADER_SHIFT)


CP_CHP_HEADER_SIZE

Размер хэшируемого поля заголовка пакета и поля IV (если IV хэшируется).
#define CP_CHP_HEADER_SIZE(f) (CP_CHP_PUREHEADER_SIZE(f) +	\
                    (((f)&CP_CHP_IV_HEADER)		\
                    ? CP_CHP_IV_SIZE(f)		\
                    : 0))


CP_CHP_REALHEADER_SIZE

Суммарный размер поля заголовка пакета и поля IV.
#define CP_CHP_REALHEADER_SIZE(f) (CP_CHP_PUREHEADER_SIZE(f) +		\
                    CP_CHP_IV_SIZE(f))


CP_CHP_HASH_SIZE

Размер поля значения хеш-функции.
#define CP_CHP_HASH_SIZE(f) (sizeof(DWORD)*						\
            (((f)&CP_CHP_HASH_MASK)				\
            ?((f&CP_CHP_HASH_SIZE_MASK)>>CP_CHP_HASH_SIZE_SHIFT)\
            :0))


CP_CHP_HASH_DATA

Указатель на поле значения хеш-функции в пакете, если поле присутствует.
#define CP_CHP_HASH_DATA(f, d, l) _CP_CHP_SAFE_CHECK_((d),(l),		\
        _CP_CHP_ADD_((d), (l)-CP_CHP_HASH_SIZE(f)),		\
        CP_CHP_HASH_SIZE(f)					\
        )


CP_CHP_HASH_LEN

Длина хэшируемого поля пакета(в случае, когда поле IV хэшируется).
#define CP_CHP_HASH_LEN(f, l) (l-CP_CHP_HASH_SIZE(f))


CP_CHP_HASH_LEN_1

Длина первого хэшируемого поля (в случае, когда поле IV не хэшируется).
#define CP_CHP_HASH_LEN_1(f) CP_CHP_PUREHEADER_SIZE(f)


CP_CHP_TRAILER_SIZE

Размер поля трейлера.
#define CP_CHP_TRAILER_SIZE(f) ((((f)&CP_CHP_TRAILER_MASK)==CP_CHP_TRAILER_MASK)	\
            ?(0)						\
            :(((f)&CP_CHP_TRAILER_MASK)>>CP_CHP_TRAILER_SHIFT))	\


CP_CHP_TRAILER_DATA

Указатель на поле трейлера в пакете, если поле присутствует.
#define CP_CHP_TRAILER_DATA(f, d, l) _CP_CHP_SAFE_CHECK_((d),(l),	\
        _CP_CHP_SUB_(CP_CHP_HASH_DATA((f),(d),(l)),		\
                    CP_CHP_TRAILER_SIZE(f)),	\
        CP_CHP_TRAILER_SIZE(f)					\
        )


CP_CHP_PAYLOAD_SIZE

Размер тела пакета.
#define CP_CHP_PAYLOAD_SIZE(f, l) ((l) -					\
                    CP_CHP_REALHEADER_SIZE(f) -		\
                    CP_CHP_TRAILER_SIZE(f) -		\
                    CP_CHP_HASH_SIZE(f))


CP_CHP_CIPHER_SIZE

Размер шифруемого поля пакета.
#define CP_CHP_CIPHER_SIZE(f, l) (					\
        (l) -							\
        CP_CHP_REALHEADER_SIZE(f) -				\
        CP_CHP_TRAILER_SIZE(f) -				\
        ((((f)&CP_CHP_TRAILER_MASK)==CP_CHP_TRAILER_MASK)	\
            ?(0)						\
            :(CP_CHP_HASH_SIZE(f)))				\
        )


CP_CHP_CIPHER_DATA

Указатель на шифруемое поле пакета.
#define CP_CHP_CIPHER_DATA(f, d, l) _CP_CHP_SAFE_CHECK_((d),(l),	\
        _CP_CHP_ADD_((d), CP_CHP_REALHEADER_SIZE(f)),		\
        CP_CHP_CIPHER_SIZE(f,l)					\
        )


CP_CHP_HASH_DATA_2

Указатель на второе хэшируемое поле пакета (в случае, когда поле IV не хэшируется).
#define CP_CHP_HASH_DATA_2(f, d, l) CP_CHP_CIPHER_DATA((f),(d),(l))


CP_CHP_HASH_LEN_2

Длина второго хэшируемого поля пакета (в случае, когда поле IV не хэшируется).
#define CP_CHP_HASH_LEN_2(f, l) (					\
        CP_CHP_CIPHER_SIZE(f,l) + CP_CHP_TRAILER_SIZE(f) -	\
        ((((f)&CP_CHP_TRAILER_MASK)==CP_CHP_TRAILER_MASK)	\
            ?(CP_CHP_HASH_SIZE(f))				\
            :(0))						\
        )


Вектор ввода вывода

Входные (и выходные) данные функций шифрования CPEncrypt(), CPCEncrypt(), CPDecrypt(), CPCDecrypt(), если в параметре dwFlags устаны флаги CP_CRYPT_HASH_PACKET и CP_CRYPT_DATA_IOVEC, а также входные данные функций хэширования CPHashData() и CPCHashData(), если в параметре dwFlags устан флаг CP_HASH_DATA_IOVEC, могут быть представлены в форме вектора ввода вывода. В этом случае данные представляются массивом структур CSP_iovec. Последовательность структур в массиве должна соответствовать последовательности фрагментов данных в пакете.

Структуры | Описание
CSP_iovec_ | Cтруктура определяет представление фрагмента данных во внешнем интерфейсе.
Макросы | Описание
CSP_UIO_MAXIOV | Максимально допустимое число фрагментов в представлении пакета вектором ввода вывода.
CSP_KERNEL_UIO_MAXIOV | Максимально допустимое число фрагментов при использовании библиотеки уровня ядра или в адресном пространстве пользователя.
CSP_UIOV_MAXBAD_LEN | Значение не инициализированного поля длины.
IOVEC_PTR | Макрос возвращает указатель на фрагмент данных с номером n в векторе ввода вывода.
IOVEC_LEN | Макрос возвращает длину фрагмента данных с номером n в векторе ввода вывода.
CP_CRYPT_DATA_IOVEC | Флаг - признак представления пакета в форме вектора ввода/вывода. Для функций CPEncrypt(), CPCEncrypt(),CPDecrypt(), CPCDecrypt() флаг должен быть установлен, если используется представление пакета в форме вектора ввода/вывода, в противном случае пакет представляется буфером. См. Шифрование и хэширование пакета .
CP_HASH_DATA_IOVEC | Флаг параметра dwFlags - признак представления данных в форме вектора ввода/вывода для функций CPHashData() и CPCHashData(). Должен быть установлен, если используется представление данных в форме вектора ввода/вывода, в противном случае данные представляются буфером.


CSP_UIO_MAXIOV

Максимально допустимое число фрагментов в представлении пакета вектором ввода вывода.
#define CSP_UIO_MAXIOV (1024-16)


CSP_KERNEL_UIO_MAXIOV

Максимально допустимое число фрагментов при использовании библиотеки уровня ядра или в адресном пространстве пользователя.
#define CSP_KERNEL_UIO_MAXIOV (1024-16)


CSP_UIOV_MAXBAD_LEN

Значение не инициализированного поля длины.
#define CSP_UIOV_MAXBAD_LEN ((CSPiov_len_type)0x7fffFFFF)


IOVEC_PTR

Макрос возвращает указатель на фрагмент данных с номером n в векторе ввода вывода.

Параметры:

  • p - указатель на первый элемент в массиве структур CSP_iovec;
  • n - номер структуры в векторе ввода вывода.

#define IOVEC_PTR(p, n) (((CSP_iovec*)p)[n].CSPiov_ptr)


IOVEC_LEN

Макрос возвращает длину фрагмента данных с номером n в векторе ввода вывода.

Параметры:

  • p - указатель на первый элемент в массиве структур CSP_iovec;
  • n - номер структуры в векторе ввода вывода.

#define IOVEC_LEN(p, n) (((CSP_iovec*)p)[n].CSPiov_len)


CP_CRYPT_DATA_IOVEC

Флаг - признак представления пакета в форме вектора ввода/вывода. Для функций CPEncrypt(), CPCEncrypt(),CPDecrypt(), CPCDecrypt() флаг должен быть установлен, если используется представление пакета в форме вектора ввода/вывода, в противном случае пакет представляется буфером. См. Шифрование и хэширование пакета .
#define CP_CRYPT_DATA_IOVEC (0x2)


CP_HASH_DATA_IOVEC

Флаг параметра dwFlags - признак представления данных в форме вектора ввода/вывода для функций CPHashData() и CPCHashData(). Должен быть установлен, если используется представление данных в форме вектора ввода/вывода, в противном случае данные представляются буфером.
#define CP_HASH_DATA_IOVEC CP_CRYPT_DATA_IOVEC


CSP_iovec_

Cтруктура определяет представление фрагмента данных во внешнем интерфейсе.

typedef struct CSP_iovec_ {
  CSPiov_len_type CSPiov_len;
  CSPiov_ptr_type CSPiov_ptr;
} CSP_iovec;

Члены

CSPiov_len
Длина фрагмента данных в байтах.
CSPiov_ptr
Указатель на фрагмент данных.

Примечания

На уровне приложений пользователя во всех Windows CSP_iovec является макросом для WSABUF, поэтому для использования CSP_iovec требуется "#include <Winsock2.h>".

На уровне приложений пользователя в POSIX (Linux/Solaris/AIX/FreeBSD) системах CSP_iovec является макросом для struct iovec, поэтому для использования CSP_iovec требуется "#include <sys/uio.h>".


Мультипакетная обработка

Функции CPEncrypt(), CPCEncrypt(),CPDecrypt(), CPCDecrypt() допускают мультипакетную обработку по технологии SIMD при использовании аппаратной платформы, поддерживающей расширения SSSE3, AVX.

Структуры | Описание
CSP_Multipacket_ | Используется только для совместимости; заменена CSP_Multipacket_ENC и CSP_Multipacket_DEC.
CSP_Multipacket_ENC_ | Структура для передачи параметров для шифрования в случае мультипакетной обработки (использования флага CP_CHP_MULTIPACKET). Мультипакет передаётся массивом структур CSP_Multipacket_ENC. Каждая структура передаёт пакет как линейный буфер, либо как IOVEC, если в параметре dwFlags установлены флаги CP_CRYPT_HASH_PACKET, CP_CHP_MULTIPACKET и CP_CRYPT_DATA_IOVEC.
CSP_Multipacket_DEC_ | Структура для передачи параметров для расшифрования в случае мультипакетной обработки (использования флага CP_CHP_MULTIPACKET). Мультипакет передаётся массивом структур CSP_Multipacket_DEC. Каждая структура передаёт пакет как линейный буфер, либо как IOVEC, если в параметре dwFlags установлены флаги CP_CRYPT_HASH_PACKET, CP_CHP_MULTIPACKET и CP_CRYPT_DATA_IOVEC.
Макросы | Описание
MultiPacket_ENC_PTR | Макрос возвращает указатель на шифруемый пакет с номером n в массиве пакетов.
MultiPacket_DEC_PTR | Макрос возвращает указатель на расшифровываемый пакет с номером n в массиве пакетов.
MultiPacket_ENC_LEN | Макрос возвращает длину шифруемого пакета с номером n в массиве пакетов либо общую длину в представлении шифруемого пакета вектором ввода-вывода.
MultiPacket_DEC_LEN | Макрос возвращает длину расшифровываемого пакета с номером n в массиве пакетов либо число элементов вектора ввода-вывода.
MultiPacket_ENC_BUFLEN | Макрос возвращает длину буфера шифруемого линейного пакета с номером n в массиве пакетов либо число элементов вектора ввода-вывода.
MultiPacket_ENC_RES Макрос возвращает результат обработки пакета с номером n в массиве пакетов. Для функций CPEncrypt(), CPCEncrypt() перед их вызовом в это поле устанавливается единица. Параметры:
  • p - указатель на первый элемент в массиве структур CSP_Multipacket_ENC;
  • n - номер структуры в массиве пакетов.
MultiPacket_DEC_RES Макрос возвращает результат обработки пакета с номером n в массиве пакетов. Для функций CPDecrypt(), CPCDecrypt() перед их вызовом в это поле устанавливается единица. После вызова функций CPDecrypt(), CPCDecrypt() значение ноль в данном поле свидетельствует, что пакет с номером n обработан корректно, значение хеш функции пакета совпало с вычисленным значением; значение единица в данном поле свидетельствует о том, что значения хеш функций не совпали. Параметры:
  • p - указатель на первый элемент в массиве структур CSP_Multipacket_DEC;
  • n - номер структуры в массиве пакетов.


MultiPacket_ENC_PTR

Макрос возвращает указатель на шифруемый пакет с номером n в массиве пакетов.

Параметры:

  • p - указатель на первый элемент в массиве структур CSP_Multipacket_ENC;
  • n - номер структуры в массиве пакетов.

#define MultiPacket_ENC_PTR(p, n) (((CSP_Multipacket_ENC*)p)[n].pbEncData)


MultiPacket_DEC_PTR

Макрос возвращает указатель на расшифровываемый пакет с номером n в массиве пакетов.

Параметры:

  • p - указатель на первый элемент в массиве структур CSP_Multipacket_DEC;
  • n - номер структуры в массиве пакетов.

#define MultiPacket_DEC_PTR(p, n) (((CSP_Multipacket_DEC*)p)[n].pbDecData)


MultiPacket_ENC_LEN

Макрос возвращает длину шифруемого пакета с номером n в массиве пакетов либо общую длину в представлении шифруемого пакета вектором ввода-вывода.

Параметры:

  • p - указатель на первый элемент в массиве структур CSP_Multipacket_ENC;
  • n - номер структуры в массиве пакетов.

#define MultiPacket_ENC_LEN(p, n) (((CSP_Multipacket_ENC*)p)[n].cbEncDataLen)


MultiPacket_DEC_LEN

Макрос возвращает длину расшифровываемого пакета с номером n в массиве пакетов либо число элементов вектора ввода-вывода.

Параметры:

  • p - указатель на первый элемент в массиве структур CSP_Multipacket_DEC;
  • n - номер структуры в массиве пакетов.

#define MultiPacket_DEC_LEN(p, n) (((CSP_Multipacket_DEC*)p)[n].dwDecDataLen)


MultiPacket_ENC_BUFLEN

Макрос возвращает длину буфера шифруемого линейного пакета с номером n в массиве пакетов либо число элементов вектора ввода-вывода.

Параметры:

  • p - указатель на первый элемент в массиве структур CSP_Multipacket_ENC;
  • n - номер структуры в массиве пакетов.

#define MultiPacket_ENC_BUFLEN(p, n) (((CSP_Multipacket_ENC*)p)[n].dwEncBufLen)


MultiPacket_ENC_RES

Макрос возвращает результат обработки пакета с номером n в массиве пакетов. Для функций CPEncrypt(), CPCEncrypt() перед их вызовом в это поле устанавливается единица. Параметры:
  • p - указатель на первый элемент в массиве структур CSP_Multipacket_ENC;
  • n - номер структуры в массиве пакетов.
#define MultiPacket_ENC_RES(p, n) (((CSP_Multipacket_ENC*)p)[n].dwEncResult)


MultiPacket_DEC_RES

Макрос возвращает результат обработки пакета с номером n в массиве пакетов. Для функций CPDecrypt(), CPCDecrypt() перед их вызовом в это поле устанавливается единица. После вызова функций CPDecrypt(), CPCDecrypt() значение ноль в данном поле свидетельствует, что пакет с номером n обработан корректно, значение хеш функции пакета совпало с вычисленным значением; значение единица в данном поле свидетельствует о том, что значения хеш функций не совпали. Параметры:
  • p - указатель на первый элемент в массиве структур CSP_Multipacket_DEC;
  • n - номер структуры в массиве пакетов.
#define MultiPacket_DEC_RES(p, n) (((CSP_Multipacket_DEC*)p)[n].dwDecResult)


CSP_Multipacket_

Используется только для совместимости; заменена CSP_Multipacket_ENC и CSP_Multipacket_DEC.
typedef struct CSP_Multipacket_ {
  BYTE * pbData;
  DWORD cbData;
  DWORD dwBufLen;
  DWORD dwResult;
} CSP_Multipacket;

Члены

pbData
указатель на линейный пакет, указатель на IOVEC.
cbData
длина линейного пакета; общая длина элементов IOVEC (при расшифровании - число элементов IOVEC).
dwBufLen
длина буфера линейного пакета, число элементов IOVEC (при расшифровании поле не используется).
dwResult
результат обработки пакета.


CSP_Multipacket_ENC_

Структура для передачи параметров для шифрования в случае мультипакетной обработки (использования флага CP_CHP_MULTIPACKET). Мультипакет передаётся массивом структур CSP_Multipacket_ENC. Каждая структура передаёт пакет как линейный буфер, либо как IOVEC, если в параметре dwFlags установлены флаги CP_CRYPT_HASH_PACKET, CP_CHP_MULTIPACKET и CP_CRYPT_DATA_IOVEC.
typedef struct CSP_Multipacket_ENC_ {
  BYTE * pbEncData;
  DWORD cbEncDataLen;
  DWORD dwEncBufLen;
  DWORD dwEncResult;
} CSP_Multipacket_ENC;

Члены

pbEncData
указатель на линейный пакет, указатель на IOVEC.
cbEncDataLen
длина линейного пакета; общая длина элементов IOVEC
dwEncBufLen
длина буфера линейного пакета, число элементов IOVEC
dwEncResult
результат обработки пакета.


CSP_Multipacket_DEC_

Структура для передачи параметров для расшифрования в случае мультипакетной обработки (использования флага CP_CHP_MULTIPACKET). Мультипакет передаётся массивом структур CSP_Multipacket_DEC. Каждая структура передаёт пакет как линейный буфер, либо как IOVEC, если в параметре dwFlags установлены флаги CP_CRYPT_HASH_PACKET, CP_CHP_MULTIPACKET и CP_CRYPT_DATA_IOVEC.
typedef struct CSP_Multipacket_DEC_ {
  BYTE * pbDecData;
  DWORD dwDecDataLen;
  DWORD reserved;
  DWORD dwDecResult;
} CSP_Multipacket_DEC;

Члены

pbDecData
указатель на линейный пакет, указатель на IOVEC.
dwDecDataLen
длина линейного пакета, число элементов IOVEC
reserved
длина буфера линейного пакета, число элементов IOVEC
dwDecResult
результат обработки пакета.


CRYPT_MODE_CBCSTRICT

Режим блочного шифрования с обратной связью на базе ГОСТ 28147-89, шифр-текст блока всегда является IV для следующего.
#define CRYPT_MODE_CBCSTRICT 1


CRYPT_MODE_CBCRFC4357

Режим блочного шифрования с обратной связью на базе ГОСТ 28147-89, согласно RFC 4357.
#define CRYPT_MODE_CBCRFC4357 31


CRYPT_MODE_CNT

Режим шифрования "гаммированием" по ГОСТ 28147-89.
#define CRYPT_MODE_CNT 3


CRYPT_MODE_CTR

Режим шифрования "гаммирование" по ГОСТ Р 34.13-2015.
#define CRYPT_MODE_CTR 32


SECRET_KEY_LEN

Длина в байтах ключа ГОСТ 28147-89 и закрытых ключей ГОСТ Р 34.10-94 и ГОСТ Р 34.10-2001.
#define SECRET_KEY_LEN 32


G28147_KEYLEN

Длина в байтах ключа ГОСТ 28147-89.

#define G28147_KEYLEN SECRET_KEY_LEN

См. также

SECRET_KEY_LEN


EXPORT_IMIT_SIZE

Длина в байтах имитовставки при импорте/экспорте.
#define EXPORT_IMIT_SIZE 4


CHECK_VALUE_SIZE

Длина в байтах контрольной величины ключа при импорте и получении параметра ключа.
#define CHECK_VALUE_SIZE 3


SEANCE_VECTOR_LEN

Длина в байтах вектора инициализации алгоритма.
#define SEANCE_VECTOR_LEN 8


MAX_CONTAINER_NAME_LEN

Максимальная разрешённая длина имени ключевого контейнера.
#define MAX_CONTAINER_NAME_LEN 260


GR3410_1_MAGIC

Признак ключей ГОСТ Р 34.10-94 и ГОСТ Р 34.10-2001.
#define GR3410_1_MAGIC 0x3147414D


G28147_MAGIC

Признак ключей ГОСТ 28147-89 и мастер ключей TLS.
#define G28147_MAGIC 0x374a51fd


DIVERS_MAGIC

Признак ключевого блоба функции диверсификации ключа.
#define DIVERS_MAGIC 0x31564944


KEXP15_MAGIC

Признак ключевого блоба алгоритма KExp15.
#define KEXP15_MAGIC 0x374a51ff


BLOB_VERSION

Текущее значение версии ключевого блоба.
#define BLOB_VERSION (BYTE)0x20


KEXP15_BLOB_VERSION

Текущее значение версии ключевого блоба KExp15.
#define KEXP15_BLOB_VERSION (BYTE)0x21


CP_CRYPT_PUBLICKEY_FROM_CERT

Флаг, устанавливающий признак получения открытого ключа из сертификата.
#define CP_CRYPT_PUBLICKEY_FROM_CERT (0x00010000)


VER_TYPE_DEBUG

Отладочная версия дистрибутива.
#define VER_TYPE_DEBUG 1


VER_TYPE_RELEASE

Релизная версия дистрибутива.
#define VER_TYPE_RELEASE 0


VER_ARCH_IA32

Архитектура IA32.
#define VER_ARCH_IA32 0


VER_ARCH_IA64

Архитектура IA64.
#define VER_ARCH_IA64 1


VER_ARCH_SPARC32

Архитектура Sparc32.
#define VER_ARCH_SPARC32 2


VER_ARCH_SPARC64

Архитектура Sparc64.
#define VER_ARCH_SPARC64 3


VER_ARCH_AMD64

Архитектура AMD64.
#define VER_ARCH_AMD64 4


VER_ARCH_ARM

Архитектура ARM.
#define VER_ARCH_ARM 5


VER_ARCH_PPC32

Архитектура PowerPC32.
#define VER_ARCH_PPC32 6


VER_ARCH_PPC64

Архитектура PowerPC64.
#define VER_ARCH_PPC64 7


VER_ARCH_ARM64

Архитектура ARM64.
#define VER_ARCH_ARM64 8


VER_ARCH_MIPS32

Архитектура MIPS32.
#define VER_ARCH_MIPS32 9


VER_OS_WINDOWS

ОС Windows.
#define VER_OS_WINDOWS 0


VER_OS_SOLARIS

ОС Solaris.
#define VER_OS_SOLARIS 1


VER_OS_FREEBSD

ОС FreeBSD.
#define VER_OS_FREEBSD 2


VER_OS_LINUX

ОС Linux.
#define VER_OS_LINUX 3


VER_OS_AIX

ОС AIX.
#define VER_OS_AIX 4


VER_OS_DARWIN

ОС Mac OS X.
#define VER_OS_DARWIN 5


VER_OS_IOS

Apple iOS.
#define VER_OS_IOS 6


VER_OS_ANDROID

ANDROID OS.
#define VER_OS_ANDROID 7


VER_OS_BITVISOR

BITVISOR_OS.
#define VER_OS_BITVISOR 8


VER_OS_UCLIBC

UCLIBC runtime.
#define VER_OS_UCLIBC 9


CPC_Kernel_Fpu_Begin_Callback

Описание функции захвата FPU в режиме ядра ОС.

Функция должна обеспечивать захват FPU (сохраняя значения регистров MMX (ST) и XMM ). Ей передаются буфер для сохранения регистров, его размер, тип функции, использующей дополнительные регистры, осуществляющей её вызов, и дополнительные параметры, по которым можно судить о целесообразности захвата.

typedef BOOL CPCAPI CPC_Kernel_Fpu_Begin_Callback(BYTE *buf,CPC_SIZE_T sz, DWORD bl_len, DWORD op_type);

Аргументы

buf
[in] Не выровненный буфер, предоставляемый провайдером для сохранения дополнительных регистров.
sz
[in] Размер буфера, переданного провайдером для сохранения дополнительных регистров.
bl_len
[in] Размер данных, обрабатываемых функцией, запросившей сохранение регистров.
op_type
[in] Тип функции, запросившей сохранение регистров. Тип может быть одним из четырёх:
Значение op_type | Тип функции
CSP_OPERATION_CIPHER1 | Неспараллеливаемая функция шифрования по ГОСТ 28147-89
CSP_OPERATION_CIPHER2 | Спараллеленная функция шифрования по ГОСТ 28147-89
CSP_OPERATION_IMIT | Функция выработки имитовставки по ГОСТ 28147-89
CSP_OPERATION_HASH | Функция хэширования по ГОСТ Р 34.11-94

Возвращаемые значения

результат захвата сопроцессора FPU.
Коды возврата | Описание
TRUE | Захват сопроцессора был осуществлён. В этом случае провайдер вызовет функцию, использующую MMX или SSE, и после неё - функцию CPC_Kernel_Fpu_End_Callback . Различные типы функций провайдера работают с разными скоростями, и для целесообразности захвата FPU передаются как тип функции провайдера, так и количество обрабатываемых данных.
FALSE | Захват не был осуществлён. В этом случае провайдер вызовет функцию, использующую только стандартный набор инструкций (универсальную).

См. также

CPC_FAST_CODE ,CPC_Kernel_Fpu_End_Callback ,CPSetProvParam() ,CPCSetProvParam()


CPC_Kernel_Fpu_End_Callback

Описание функции освобождения FPU в режиме ядра ОС.

Функция должна обеспечивать освобождение FPU (восстанавливая значения регистров MMX (ST) и XMM ). Ей передаются буфер для сохранения регистров, его размер, тип функции, использовавшей в провайдере дополнительные регистры, и осуществившей вызов парной функции CPC_Kernel_Fpu_Begin_Callback .

typedef BOOL CPCAPI CPC_Kernel_Fpu_End_Callback(BYTE *buf,CPC_SIZE_T sz,DWORD op_type);

Аргументы

buf
[in] Буфер, предоставляемый провайдером для сохранения дополнительных регистров. В нем должна была сохранить состояние сопроцессора функция CPC_Kernel_Fpu_Begin_Callback .
sz
[in] Размер буфера, переданного провайдером для сохранения дополнительных регистров.
op_type
[in] Тип функции, запросившей сохранение регистров. Тип может быть одним из четырех:
Значение op_type | Тип функции
CSP_OPERATION_CIPHER1 | Неспараллеливаемая функция шифрования по ГОСТ 28147-89
CSP_OPERATION_CIPHER2 | Спараллеленная функция шифрования по ГОСТ 28147-89
CSP_OPERATION_IMIT | Функция выработки имитовставки по ГОСТ 28147-89
CSP_OPERATION_HASH | Функция хэширования по ГОСТ Р 34.11-94

Возвращаемые значения

результат освобождения сопроцессора FPU.
Коды возврата | Описание
TRUE | Освобождение сопроцессора было осуществлено.
FALSE | Освобождение не было осуществлено.

См. также

CPC_FAST_CODE ,CPC_Kernel_Fpu_Begin_Callback ,CPSetProvParam() ,CPCSetProvParam()


_CRYPT_FKC_DH_CHECK_VAL

Значения параметра "проверка открытого ключа в операции Диффи-Хеллмана". При установке параметра передается переменной типа DWORD.

typedef enum _CRYPT_FKC_DH_CHECK_VAL {
  dh_check_disable = 1,
  dh_check_enable = 2
} CRYPT_FKC_DH_CHECK_VAL;

Элементы перечисления:

dh_check_disable
Проверка открытого ключа не осуществляется
dh_check_enable
Проверка открытого ключа осуществляется

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CPGetProvParam ,CPSetProvParam ,CRYPT_FKC_DH_CHECK


_PUBLICKEYSTRUC

Структура PUBLICKEYSTRUC, также известная, как структура BLOBHEADER, указывает тип ключевого блоба и алгоритм ключа, находящегося в нём. Экземпляр этой структуры находится в начале поля pbData каждого ключевого блоба.

typedef struct _PUBLICKEYSTRUC {
  BYTE bType;
  BYTE bVersion;
  WORD reserved;
  ALG_ID aiKeyAlg;
} BLOBHEADER, PUBLICKEYSTRUC;

Члены

bType
Тип ключевого блоба. Поддерживаются следующие типы ключевых блобов:
bType | Описание
PUBLICKEYBLOB | Предназначен для транспорта открытых ключей.
PRIVATEKEYBLOB | Предназначен для транспорта ключевых пар (секретных ключей).
SIMPLEBLOB | Предназначен для транспорта сессионых ключей.
bVersion
Номер версии формата ключевого блоба. В настоящий момент версия всегда должна быть равна 0x02.
reserved
Зарезервировано для использования в будущем. Должно устанавливаться в 0.
aiKeyAlg
Алгоритм ключа, содержащегося в ключевом блобе.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Windows прототип описан в файле Wincrypt.h, Unix - CSP_Wincrypt.h

См. также

CRYPT_PUBKEY_INFO_HEADER ,CRYPT_SIMPLEBLOB_HEADER ,CRYPT_PUBLICKEYBLOB ,CRYPT_PRIVATEKEYBLOB ,CRYPT_SIMPLEBLOB


_PROV_PP_VERSION_EX

Структура описывает версию СКЗИ, ПКЗИ, тип сборки, аппаратную архитектуру и ОС, для которой предназначен продукт.
typedef struct _PROV_PP_VERSION_EX {
  DWORD PKZI_Build;
  DWORD SKZI_Build;
  DWORD TypeDebRel;
  DWORD Architecture;
  DWORD OS;
} PROV_PP_VERSION_EX;

Члены

PKZI_Build
Версия ПКЗИ.
SKZI_Build
Версия СКЗИ.
TypeDebRel
Тип сборки: VER_TYPE_DEBUG, VER_TYPE_RELEASE.
Architecture
Аппаратная архитектура: VER_ARCH_IA32, VER_ARCH_IA64, VER_ARCH_SPARC32, VER_ARCH_SPARC64, VER_ARCH_AMD64, VER_ARCH_ARM, VER_ARCH_ARM64, VER_ARCH_PPC32, VER_ARCH_PPC64.
OS
Тип ОС: VER_OS_WINDOWS, VER_OS_SOLARIS, VER_OS_FREEBSD, VER_OS_LINUX, VER_OS_AIX.


_SELFTEST_HEADER

Заголовок результата встроенного тестирования и контроля целостности СКЗИ.
typedef struct _SELFTEST_HEADER {
  DWORD PKZI_Build;
  DWORD SKZI_Build;
  DWORD TypeDebRel;
  DWORD Architecture;
  DWORD OS;
  DWORD TesterFlags;
  DWORD TotalChecksums;
  DWORD UnwrittenChecksums;
} SELFTEST_HEADER;

Члены

PKZI_Build
Версия ПКЗИ.
SKZI_Build
Версия СКЗИ.
TypeDebRel
Тип сборки: VER_TYPE_DEBUG, VER_TYPE_RELEASE.
Architecture
Аппаратная архитектура: VER_ARCH_IA32, VER_ARCH_IA64, VER_ARCH_SPARC32, VER_ARCH_SPARC64, VER_ARCH_AMD64, VER_ARCH_ARM, VER_ARCH_ARM64, VER_ARCH_PPC32, VER_ARCH_PPC64.
OS
Тип ОС: VER_OS_WINDOWS, VER_OS_SOLARIS, VER_OS_FREEBSD, VER_OS_LINUX, VER_OS_AIX.
TesterFlags
Битовый вектор ошибок встроенных тестов, включает результат контроля целостности. В случае успеха, должен быть равен 0.
TotalChecksums
Общее количество модулей для которых была проведена проверка целостности. Всегда больше или равен 1.
UnwrittenChecksums
Количество модулей, информация о которых не была записана в поле Checksums структуры PROV_PP_SELFTEST, по причине недостаточного количества памяти, выделенной для структуры. Если памяти достаточно, равно 0.


_CPU_INFO

Структура описывает время работы (тики) процессора в простое, режиме ядра, пользовательском режиме, Nice режиме, и полное время работы процессора.
typedef struct _CPU_INFO {
  ULONGLONG Idle;
  ULONGLONG Kernel;
  ULONGLONG User;
  ULONGLONG Nice;
  DWORD dwProcNumber;
  DWORD Dummy;
} CPU_INFO;

Члены

Idle
Kernel
User
Nice
dwProcNumber
Dummy


_SELFTEST_CHECKSUM_ELEMENT

Результат контроля целостности модуля.
typedef struct _SELFTEST_CHECKSUM_ELEMENT {
  char BlockName[40];
  BYTE InitialHash[32];
  BYTE CalculatedHash[32];
} SELFTEST_CHECKSUM_ELEMENT;

Члены

BlockName
Название модуля.
InitialHash
Эталонная контрольная сумма.
CalculatedHash
Фактическая контрольная сумма.


_PROV_PP_SELFTEST

Результат встроенного тестирования и контроля целостности СКЗИ.
typedef struct _PROV_PP_SELFTEST {
  SELFTEST_HEADER Header;
  SELFTEST_CHECKSUM_ELEMENT Checksums[1];
} PROV_PP_SELFTEST;

Члены

Header
Заголовок SELFTEST_HEADER .
Checksums
Массив SELFTEST_CHECKSUM_ELEMENT размера Header.TotalChecksums.


_CRYPT_SIMPLEBLOB_HEADER

Структура CRYPT_SIMPLEBLOB_HEADER является расширением структуры BLOBHEADER и находится в начале поля pbData ключевого блоба типа SIMPLEBLOB для ключей "КриптоПро CSP".

typedef struct _CRYPT_SIMPLEBLOB_HEADER {
  BLOBHEADER BlobHeader;
  DWORD Magic;
  ALG_ID EncryptKeyAlgId;
} CRYPT_SIMPLEBLOB_HEADER;

Члены

BlobHeader
Общий заголовок ключевого блоба. Определяет алгоритм ключа находящегося в ключевом блобе. См. _PUBLICKEYSTRUC .
Magic
Признак ключей по ГОСТ 28147-89 или мастер ключей TLS, устанавливается в G28147_MAGIC .
EncryptKeyAlgId
Определяет алгоритм экспорта ключа. Этот алгоритм является параметром ключа экспорта. См. CPGetKeyParam .

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

_PUBLICKEYSTRUC ,PCRYPT_SIMPLEBLOB ,CPExportKey ,CPGetKeyParam


_CRYPT_SIMPLEBLOB

Псевдоструктура (т. е. недоопределенная структура) CRYPT_SIMPLEBLOB полностью описывает ключевой блоб типа SIMPLEBLOB для ключей "КриптоПро CSP".

typedef struct _CRYPT_SIMPLEBLOB {
  CRYPT_SIMPLEBLOB_HEADER tSimpleBlobHeader;
  BYTE bSV[SEANCE_VECTOR_LEN];
  BYTE bEncryptedKey[G28147_KEYLEN];
  BYTE bMacKey[EXPORT_IMIT_SIZE];
  BYTE bEncryptionParamSet[1];
} CRYPT_SIMPLEBLOB, *PCRYPT_SIMPLEBLOB;

Члены

tSimpleBlobHeader
Общий заголовок ключевого блоба типа SIMPLEBLOB "КриптоПро CSP".
bSV
Вектор инициализации для алгоритма CALG_PRO_EXPORT. См. SEANCE_VECTOR_LEN .
bEncryptedKey
Зашифрованный ключ ГОСТ 28147-89. См. G28147_KEYLEN .
bMacKey
Имитовставка по ГОСТ 28147-89 на ключ. Рассчитывается до зашифрования и проверяется после расшифрования. См. EXPORT_IMIT_SIZE .
bEncryptionParamSet
Содержит ASN1 структуру в DER кодировке, определяющую параметры алгоритма шифрования ГОСТ 28147-89:

      encryptionParamSet
          OBJECT IDENTIFIER (
              id-Gost28147-89-TestParamSet |      -- Only for tests use
              id-Gost28147-89-CryptoPro-A-ParamSet |
              id-Gost28147-89-CryptoPro-B-ParamSet |
              id-Gost28147-89-CryptoPro-C-ParamSet |
              id-Gost28147-89-CryptoPro-D-ParamSet |
              id-Gost28147-89-CryptoPro-Simple-A-ParamSet |
              id-Gost28147-89-CryptoPro-Simple-B-ParamSet |
              id-Gost28147-89-CryptoPro-Simple-C-ParamSet |
              id-Gost28147-89-CryptoPro-Simple-D-ParamSet

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CRYPT_SIMPLEBLOB_HEADER ,CPExportKey ,CPGetKeyParam


_CRYPT_SIMPLEBLOB_512

Псевдоструктура (т. е. недоопределенная структура) CRYPT_SIMPLEBLOB полностью описывает ключевой блоб типа SIMPLEBLOB для ключей "КриптоПро CSP".

typedef struct _CRYPT_SIMPLEBLOB_512 {
  CRYPT_SIMPLEBLOB_HEADER tSimpleBlobHeader;
  BYTE bSV[SEANCE_VECTOR_LEN];
  BYTE bEncryptedKey[SYMMETRIC_KEY_512_LEN];
  BYTE bMacKey[EXPORT_IMIT_SIZE];
  BYTE bEncryptionParamSet[1];
} CRYPT_SIMPLEBLOB_512, *PCRYPT_SIMPLEBLOB_512;

Члены

tSimpleBlobHeader
Общий заголовок ключевого блоба типа SIMPLEBLOB "КриптоПро CSP".
bSV
Вектор инициализации для алгоритма CALG_PRO_EXPORT. См. SEANCE_VECTOR_LEN .
bEncryptedKey
Зашифрованный ключ CALG_SYMMETRIC_512. См. G28147_KEYLEN .
bMacKey
Имитовставка по ГОСТ 28147-89 на ключ. Рассчитывается до зашифрования и проверяется после расшифрования. См. EXPORT_IMIT_SIZE .
bEncryptionParamSet
Содержит ASN1 структуру в DER кодировке, определяющую параметры алгоритма шифрования ГОСТ 28147-89:

      encryptionParamSet
          OBJECT IDENTIFIER (
              id-Gost28147-89-TestParamSet |      -- Only for tests use
              id-Gost28147-89-CryptoPro-A-ParamSet |
              id-Gost28147-89-CryptoPro-B-ParamSet |
              id-Gost28147-89-CryptoPro-C-ParamSet |
              id-Gost28147-89-CryptoPro-D-ParamSet |
              id-Gost28147-89-CryptoPro-Simple-A-ParamSet |
              id-Gost28147-89-CryptoPro-Simple-B-ParamSet |
              id-Gost28147-89-CryptoPro-Simple-C-ParamSet |
              id-Gost28147-89-CryptoPro-Simple-D-ParamSet

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CRYPT_SIMPLEBLOB_HEADER ,CPExportKey ,CPGetKeyParam


_CRYPT_OPAQUEBLOB

Псевдоструктура (т. е. недоопределенная структура) CRYPT_OPAQUEBLOB полностью описывает ключевой блоб типа OPAQUEKEYLOB для ключей "КриптоПро CSP".

typedef struct _CRYPT_OPAQUEBLOB {
  CRYPT_SIMPLEBLOB_HEADER tSimpleBlobHeader;
  BYTE bSV[SEANCE_VECTOR_LEN];
  BYTE bEncryptedKey[G28147_KEYLEN];
  BYTE bMacKey[EXPORT_IMIT_SIZE];
  BYTE bEncryptedInitKey[G28147_KEYLEN];
  BYTE bMacInitKey[EXPORT_IMIT_SIZE];
  BYTE bCurrentIV[SEANCE_VECTOR_LEN];
  BYTE bChainBlock[8];
  BYTE bAccCiphertextLen[sizeof(DWORD)];
  BYTE bCommAccCiphertextLen[sizeof(DWORD)];
  BYTE bCommCipherTextLenOnBaseKey[sizeof(DWORD)];
  BYTE bCipherMode[sizeof(DWORD)];
  BYTE bMixMode[sizeof(DWORD)];
  BYTE bFlags[4];
  BYTE bPaddingMode[sizeof(DWORD)];
  BYTE bAlgId[sizeof(ALG_ID)];
  BYTE bCommonFlags[4];
  BYTE bCheckSum[sizeof(DWORD)];
  BYTE bEncryptionParamSet[1];
} CRYPT_OPAQUEBLOB, *PCRYPT_OPAQUEBLOB;

Члены

tSimpleBlobHeader
Общий заголовок ключевого блоба типа SIMPLEBLOB "КриптоПро CSP".
bSV
Вектор инициализации для алгоритма CALG_PRO_EXPORT. См. SEANCE_VECTOR_LEN .
bEncryptedKey
Зашифрованный ключ ГОСТ 28147-89. См. G28147_KEYLEN .
bMacKey
Имитовставка по ГОСТ 28147-89 на ключ. Рассчитывается до зашифрования и проверяется после расшифрования. См. EXPORT_IMIT_SIZE .
bEncryptedInitKey
Зашифрованный ключ ГОСТ 28147-89. См. G28147_KEYLEN .
bMacInitKey
Имитовставка по ГОСТ 28147-89 на ключ. Рассчитывается до зашифрования и проверяется после расшифрования. См. EXPORT_IMIT_SIZE .
bCurrentIV
Вектор инициализации шифратора. См. SEANCE_VECTOR_LEN .
bChainBlock
Блок зацепления. Использование блока зависит от режима шифрования.
bAccCiphertextLen
Накопленная длина шифрованного текста в текущем шифровании.
bCommAccCiphertextLen
Накопленная длина шифрованного текста после финализаций.
bCommCipherTextLenOnBaseKey
Накопленная нагрузка на базовый ключ.
bCipherMode
bMixMode
bFlags
bPaddingMode
bAlgId
bCommonFlags
bCheckSum
bEncryptionParamSet
Содержит ASN1 структуру в DER кодировке, определяющую параметры алгоритма шифрования ГОСТ 28147-89:

      encryptionParamSet
          OBJECT IDENTIFIER (
              id-Gost28147-89-TestParamSet |      -- Only for tests use
              id-Gost28147-89-CryptoPro-A-ParamSet |
              id-Gost28147-89-CryptoPro-B-ParamSet |
              id-Gost28147-89-CryptoPro-C-ParamSet |
              id-Gost28147-89-CryptoPro-D-ParamSet |
              id-Gost28147-89-CryptoPro-Simple-A-ParamSet |
              id-Gost28147-89-CryptoPro-Simple-B-ParamSet |
              id-Gost28147-89-CryptoPro-Simple-C-ParamSet |
              id-Gost28147-89-CryptoPro-Simple-D-ParamSet

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CRYPT_SIMPLEBLOB_HEADER ,CPExportKey ,CPImportKey


_CRYPT_PUBKEYPARAM

Структура CRYPT_PUBKEYPARAM содержит признак ключей по ГОСТ Р 34.10-2001.

typedef struct _CRYPT_PUBKEYPARAM {
  DWORD Magic;
  DWORD BitLen;
} CRYPT_PUBKEYPARAM, *LPCRYPT_PUBKEYPARAM;

Члены

Magic
Признак ключей по ГОСТ Р 34.10-2001 устанавливается в GR3410_1_MAGIC .
BitLen
Длина открытого ключа в битах.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CRYPT_PUBKEY_INFO_HEADER ,CPExportKey ,CPGetKeyParam


_CRYPT_PUBKEY_INFO_HEADER

Структура CRYPT_PUBKEY_INFO_HEADER содержит заголовок блоба открытого ключа или блоба ключевой пары по ГОСТ Р 34.10-2001.

typedef struct _CRYPT_PUBKEY_INFO_HEADER {
  BLOBHEADER BlobHeader;
  CRYPT_PUBKEYPARAM KeyParam;
} CRYPT_PUBKEY_INFO_HEADER;

Члены

BlobHeader
Общий заголовок ключевого блоба. Определяет его тип и алгоритм ключа находящегося в ключевом блобе. Для открытых ключей алгоритм ключа всегда, либо CALG_GR3410, либо CALG_GR3410EL. Для ключевых пар алгоритм отражает её назначение. См. _PUBLICKEYSTRUC .
KeyParam
Основной признак и длина ключей ГОСТ Р 34.10-2001.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

_PUBLICKEYSTRUC ,CRYPT_PUBKEYPARAM ,CPExportKey ,CPGetKeyParam


_CRYPT_PUBLICKEYBLOB

Псевдоструктура CRYPT_PUBLICKEYBLOB полностью описывает ключевой блоб типа PUBLICKEYBLOB для ключей "КриптоПро CSP".

typedef struct _CRYPT_PUBLICKEYBLOB {
  CRYPT_PUBKEY_INFO_HEADER tPublicKeyParam;
  BYTE bASN1GostR3410_2001_PublicKeyParameters[1];
  BYTE bPublicKey[1];
} CRYPT_PUBLICKEYBLOB, *PCRYPT_PUBLICKEYBLOB;

Члены

tPublicKeyParam
Общий заголовок ключевого блоба типа PUBLICKEYBLOB "КриптоПро CSP".
bASN1GostR3410_2001_PublicKeyParameters
Содержит ASN1 структуру в DER кодировке, определяющую параметры открытого ключа, как описано типом GostR3410-2001-PublicKeyParameters CPPK [RFC 4491] и CPALGS [RFC 4357].
bPublicKey
Содержит открытый ключ в сетевом представлении (ASN1 DER) как описано типом GostR3410-2001-PublicKey CPPK [RFC 4491]. Длина массива равна tPublicKeyParam.KeyParam.BitLen/8.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CRYPT_PUBKEY_INFO_HEADER ,CPExportKey ,CPGetKeyParam


_CRYPT_PRIVATEKEYBLOB

Псевдоструктура CRYPT_PRIVATEKEYBLOB полностью описывает ключевой блоб типа PRIVATEKEYBLOB для ключей "КриптоПро CSP".

typedef struct _CRYPT_PRIVATEKEYBLOB {
  CRYPT_PUBKEY_INFO_HEADER tPublicKeyParam;
  BYTE bExportedKeys[1];
} CRYPT_PRIVATEKEYBLOB, *PCRYPT_PRIVATEKEYBLOB;

Члены

tPublicKeyParam
Общий заголовок ключевого блоба типа PRIVATEKEYBLOB "КриптоПро CSP".
bExportedKeys

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CRYPT_PUBKEY_INFO_HEADER ,CPExportKey ,CPGetKeyParam


_CRYPT_DIVERSBLOBHEADER

Структура CRYPT_DIVERSBLOBHEADER описывает блоб типа DIVERSBLOB для процедуры диверсификации ключей КриптоПро CSP.

typedef struct _CRYPT_DIVERSBLOBHEADER {
  BLOBHEADER BlobHeader;
  ALG_ID aiDiversAlgId;
  DWORD dwDiversMagic;
  DWORD cbDiversData;
} CRYPT_DIVERSBLOBHEADER, *LPCRYPT_DIVERSBLOBHEADER;

Члены

BlobHeader
Общий заголовок блоба, диверсифицирующего ключ.
aiDiversAlgId
Определяет алгоритм диверсификации ключа. Устанавливается в CALG_PRO_DIVERS, CALG_RIC_DIVERS или CALG_PRO12_DIVERS. При указании CALG_PRO_DIVERS диверсификация производится в соответствии с алгоритмом, описанным в п. 7 RFC 4357. При указании CALG_PRO12_DIVERS диверсификация производится в соответствии с алгоритмом, описанным в п. 4.5 Рекомендаций по стандартизации "Использование криптографических алгоритмов, соответствующих применению стандартов ГОСТ Р 34.10-2012 И ГОСТ Р 34.11-2012", утвержденных ТК 26 "Криптографическая защита информации".
dwDiversMagic
Признак диверсификации ключа, устанавливается в DIVERS_MAGIC .
cbDiversData
Длина данных, по которым диверсифицируется ключ.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CRYPT_DIVERSBLOB ,CPImportKey


_CRYPT_DIVERSBLOB

Структура CRYPT_DIVERSBLOB описывает блоб типа DIVERSBLOB для процедуры диверсификации ключей КриптоПро CSP.

typedef struct _CRYPT_DIVERSBLOB {
  CRYPT_DIVERSBLOBHEADER DiversBlobHeader;
  BYTE bDiversData[1];
} CRYPT_DIVERSBLOB, *LPCRYPT_DIVERSBLOB;

Члены

DiversBlobHeader
Заголовок блоба, диверсифицирующего ключ.
bDiversData
Данные, по которым диверсифицируется ключ.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CRYPT_DIVERSBLOBHEADER ,CPImportKey


_CRYPT_KDF_TREE_DIVERSBLOB_HEADER

Структура CRYPT_KDF_TREE_DIVERSBLOB_HEADER описывает блоб типа KDF_TREE_DIVERSBLOB для процедуры диверсификации КриптоПро CSP, предусматривающей возможность выработки нескольких ключей.

typedef struct _CRYPT_KDF_TREE_DIVERSBLOB_HEADER {
  BLOBHEADER BlobHeader;
  ALG_ID aiDiversAlgId;
  DWORD dwIterNum;
} CRYPT_KDF_TREE_DIVERSBLOB_HEADER, *LPCRYPT_KDF_TREE_DIVERSBLOB_HEADER;

Члены

BlobHeader
Общий заголовок блоба, диверсифицирующего ключ.
aiDiversAlgId
Определяет алгоритм диверсификации ключей. Устанавливается в CALG_KDF_TREE_GOSTR3411_2012_256. Диверсификация производится в соответствии с алгоритмом, описанным в п. 4.5 рекомендаций по стандартизации "Криптографические алгоритмы, сопутствующие применению алгоритмов электронной цифровой подписи и функции хэширования", утвержденных ТК 26 "Криптографическая защита информации".
dwIterNum
Определяет номер результирующего ключа.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CRYPT_KDF_TREE_DIVERSBLOB ,CPImportKey


_CRYPT_KDF_TREE_DIVERS_INFO

Структура CRYPT_KDF_TREE_DIVERS_INFO содержит параметры R, L, длины Seed и Label для процедуры диверсификации КриптоПро CSP, предусматривающей возможность выработки нескольких ключей.

typedef struct _CRYPT_KDF_TREE_DIVERS_INFO {
  DWORD L_value;
  DWORD R_value;
  DWORD dwSeedLen;
  DWORD dwLabelLen;
} CRYPT_KDF_TREE_DIVERS_INFO, *LPCRYPT_KDF_TREE_DIVERS_INFO;

Члены

L_value
Значение L для алгоритма диверсификации
R_value
Значение R для алгоритма диверсификации
dwSeedLen
Длина значения Seed для алгоритма диверсификации
dwLabelLen
Длина значения Label для алгоритма диверсификации

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CRYPT_KDF_TREE_DIVERSBLOB ,CPImportKey


_CRYPT_KDF_TREE_DIVERSBLOB

Структура CRYPT_KDF_TREE_DIVERSBLOB описывает блоб типа KDF_TREE_DIVERSBLOB для процедуры диверсификации КриптоПро CSP, предусматривающей возможность выработки нескольких ключей.

typedef struct _CRYPT_KDF_TREE_DIVERSBLOB {
  CRYPT_KDF_TREE_DIVERSBLOB_HEADER KdfTreeBlobHeader;
  CRYPT_KDF_TREE_DIVERS_INFO KdfTreeDiversInfo;
  BYTE bDiversData[1];
} CRYPT_KDF_TREE_DIVERSBLOB, *LPCRYPT_KDF_TREE_DIVERSBLOB;

Члены

KdfTreeBlobHeader
Заголовок блоба, диверсифицирующего ключ. Содержит общий заголовок блоба, алгоритм диверсификации и номер результирующего ключа.
KdfTreeDiversInfo
Структура, содержащая общую информацию о диверсификации: параметры R, L, длины Seed и Label.
bDiversData
Массив длины KdfTreeDiversInfo.dwSeedLen + KdfTreeDiversInfo.dwLabelLen, содержащий информацию о диверсификации: значения Seed и Label

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CRYPT_KDF_TREE_DIVERSBLOB_HEADER ,CRYPT_KDF_TREE_DIVERS_INFO ,CPImportKey


_CRYPT_PIN_NK_PARAM

Структура передачи информации для слияния частей контейнера.

typedef struct _CRYPT_PIN_NK_PARAM {
  short n;
  short k;
  DWORD * parts;
} CRYPT_PIN_NK_PARAM;

Члены

n
Количество передаваемых частей.
k
Количество частей для загрузки.
parts
32-битные внутренние идентификаторы частей контейнера.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CPSetProvParam


_CRYPT_PIN_PARAM

Структура передачи информации для: 1) смены пароля контейнера, 2) указания способа доступа к контейнеру (имя, handle, пароль), на ключе которого зашифровано содержимое другого контейнера.

typedef struct _CRYPT_PIN_PARAM {
  BYTE type;
  CRYPT_PIN_SOURCE dest;
} CRYPT_PIN_PARAM;

Члены

type
Тип данных. CRYPT_PIN_PASSWD - пароль или PIN, CRYPT_PIN_ENCRYPTION - HANDLE контейнера зашифрования. CRYPT_PIN_QUERY - тип и значение выбираются в окне, CRYPT_PIN_CLEAR - очистить пароль. CRYPT_PIN_NK - разбить на части k из n
dest
Данные соответствующего типа

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CPSetProvParam


_CRYPT_NK_INFO_PARAM

Структура получения информации о контейнере разделенного на части.

typedef struct _CRYPT_NK_INFO_PARAM {
  short n;
  short k;
  char parts[1];
} CRYPT_NK_INFO_PARAM;

Члены

n
Количество частей, на которые разделен контейнер.
k
Количество частей, достаточных для получения колюча.
parts
Последовательность n ASCIIZ строк.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CPGetProvParam


_CRYPT_PASSWD_INFO_PARAM

Структура для получения информации о пароле на контейнер.

typedef struct _CRYPT_PASSWD_INFO_PARAM {
  unsigned min_passwd_length;
  unsigned max_passwd_length;
  unsigned passwd_type;
} CRYPT_PASSWD_INFO_PARAM;

Члены

min_passwd_length
Минимальный допустимый размер пароля.
max_passwd_length
Максимальный допустимый размер пароля.
passwd_type
Тип пароля.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CPGetProvParam


_CRYPT_PIN_INFO_SOURCE

Структура для получения информации о пароле на контейнер.

typedef union _CRYPT_PIN_INFO_SOURCE {
  CRYPT_PASSWD_INFO_PARAM passwd;
  CRYPT_NK_INFO_PARAM nk_info;
  char encryption[1];
} CRYPT_PIN_INFO_SOURCE;

Члены

passwd
nk_info
encryption

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CPGetProvParam, CRYPT_PASSWD_INFO_PARAM, CRYPT_NK_INFO_PARAM


_CRYPT_PIN_INFO

Структура для получения информации о пароле на контейнер.

typedef struct _CRYPT_PIN_INFO {
  BYTE type;
  CRYPT_PIN_INFO_SOURCE dest;
} CRYPT_PIN_INFO;

Члены

type
Тип данных. CRYPT_PIN_UNKNOWN - тип неизвестен CRYPT_PIN_PASSWD - пароль или PIN, CRYPT_PIN_ENCRYPTION - HANDLE контейнера зашифрования. CRYPT_PIN_NK - разбить на части k из n CRYPT_PIN_HARDWARE_PROTECTION - тип защиты определяется аппаратным модулем CRYPT_PIN_CLEAR - пароль для аутентентификации не требуется либо установлен по умолчанию
dest
Данные соответствующего типа

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CPGetProvParam, CRYPT_PIN_INFO_SOURCE


_CRYPT_FKC_EKE_AUTH_INFO_PARAM

Структура получения информации о пароле контейнера для аутентификации по EKE.

typedef struct _CRYPT_FKC_EKE_AUTH_INFO_PARAM {
  unsigned min_passwd_length;
  unsigned max_passwd_length;
  unsigned count_eke;
  unsigned count_dh;
  unsigned count_sig;
  unsigned count_err;
  unsigned count_cerr;
  char fname[1];
} CRYPT_FKC_EKE_AUTH_INFO_PARAM;

Члены

min_passwd_length
Минимальный допустимый размер пароля.
max_passwd_length
Максимальный допустимый размер пароля.
count_eke
Счетчик оставшихся операций EKE.
count_dh
Счетчик оставшихся операций Диффи-Хеллмана.
count_sig
Счетчик оставшихся операций подписи.
count_err
Счетчик оставшихся ошибок.
count_cerr
Счетчик оставшихся последовательных ошибок.
fname
UTF8Z-строка дружественного имени.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CPSetProvParam


_CRYPT_FKC_PIN_INFO_SOURCE

Структура для получения информации о пароле на контейнер.

typedef union _CRYPT_FKC_PIN_INFO_SOURCE {
  CRYPT_PIN_INFO_SOURCE passwd;
  CRYPT_FKC_EKE_AUTH_INFO_PARAM eke_passwd;
} CRYPT_FKC_PIN_INFO_SOURCE;

Члены

passwd
обычный пароль.
eke_passwd
пароль по EKE.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CPGetProvParam, CRYPT_PIN_INFO_SOURCE, CRYPT_FKC_EKE_AUTH_INFO_PARAM


_CRYPT_FKC_PIN_INFO

Структура для получения информации о пароле на контейнер.

typedef struct _CRYPT_FKC_PIN_INFO {
  BYTE type;
  CRYPT_FKC_PIN_INFO_SOURCE dest;
} CRYPT_FKC_PIN_INFO;

Члены

type
Тип данных. CRYPT_PIN_FKC_EKE - пароль передается FKC контейнеру по EKE. Другие типы как в CSP.
dest
Данные соответствующего типа

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CPGetProvParam, CRYPT_FKC_PIN_INFO_SOURCE


_CRYPT_FKC_DH_CHECK

Структура для получения статуса проверки открытого ключа. Получает и устанавливает параметр "проверка открытого ключа в операции Диффи-Хеллмана" для провайдеров FKC ( PP_FKC_DH_CHECK ).

typedef struct _CRYPT_FKC_DH_CHECK {
  CRYPT_FKC_DH_CHECK_VAL checkdh;
  BOOL is_writable;
} CRYPT_FKC_DH_CHECK;

Члены

checkdh
is_writable
можно ли установить параметру новое значение

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CPGetProvParam ,CPSetProvParam ,CRYPT_FKC_DH_CHECK_VAL


_CRYPT_CACHE_SIZE

Структура для получения и установки настроек кэширования контейнеров.

typedef struct _CRYPT_CACHE_SIZE {
  DWORD cache_size;
  DWORD max_cache_size;
  BOOL is_writable;
} CRYPT_CACHE_SIZE;

Члены

cache_size
Размер кэша.
max_cache_size
Максимальный размер кэша.
is_writable
см. CACHE_RO

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CPGetProvParam ,CPSetProvParam


_CRYPT_ENUMREADER_INFO

Блоб с информацией о считывателе, представляющий собой сериализованную псевдоструктуру.

typedef struct _CRYPT_ENUMREADER_INFO {
  char szNickName[1];
  char szName[1];
  BYTE Flags;
} CRYPT_ENUMREADER_INFO;

Члены

szNickName
NickName считывателя - NULL-терминированная строка.
szName
Имя считывателя - NULL-терминированная строка.
Flags
Флаги считывателя.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CPGetProvParam


_CRYPT_ENUMREADER_INFO_MEDIA

Блоб с информацией о считывателе, представляющий собой сериализованную псевдоструктуру.

typedef struct _CRYPT_ENUMREADER_INFO_MEDIA {
  char szNickName[1];
  char szName[1];
  char szMedia[1];
  BYTE Flags;
} CRYPT_ENUMREADER_INFO_MEDIA;

Члены

szNickName
NickName считывателя - NULL-терминированная строка.
szName
Имя считывателя - NULL-терминированная строка.
szMedia
NULL-терминированная cтрока с UNIQUE-именем носителя или статусом, если UNIQUE не удалось получить:
szMedia | Описание
NO_MEDIA | Карта не вставлена
NO_UNIQUE | Носитель не поддерживает UNIQUE (NB: для USB-Flash-устройств на Unix не будет UNIQUE, а на Windows – будет)
INVALID_MEDIA | При работе с носителем возникли ошибки
IS_FKC | ФКН-носитель в не-ФКН-провайдере
NO_FKC | Не-ФКН-носитель в ФКН-провайдере
GEM_35000030CFE53C70 | Пример UNIQUE-имени
rutoken_2a7d64bb | Пример UNIQUE-имени
JACARTA_0b52002140489243 | Пример UNIQUE-имени
ESMART_50CF20508942 | Пример UNIQUE-имени
1082C025 | Пример UNIQUE-имени
Flags
Флаги считывателя.

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CPGetProvParam


_CRYPT_HASH_BLOB_EX

Структура передачи информации для получения и установки разделённого значения параметра R для ЭЦП на базе функционального ключевого носителя.

typedef struct _CRYPT_HASH_BLOB_EX {
  CRYPT_PUBKEY_INFO_HEADER tPublicKeyParam;
  BYTE pbData[2 *SECRET_KEY_LEN];
} CRYPT_HASH_BLOB_EX, *PCRYPT_HASH_BLOB_EX;

Члены

tPublicKeyParam
pbData

См. также

CPGetHashParam ,CPSetHashParam


_CRYPT_KEY_PERIOD

Структура для задания периодов действия ключей во вновь создаваемом контейнере.

typedef struct _CRYPT_KEY_PERIOD {
  LONG privateKeySeconds;
  LONG publicKeySeconds;
} CRYPT_KEY_PERIOD, *PCRYPT_KEY_PERIOD;

Члены

privateKeySeconds
Период действия закрытого ключа, в секундах.
publicKeySeconds
Период действия открытого ключа, в секундах.

См. также

CPGetProvParam ,CPSetProvParam


_TOKEN_VERIFYDATA

Структура передачи информации функции хэширования по алгоритму CALG_EKEVERIFY_HASH.

typedef struct _TOKEN_VERIFYDATA {
  BYTE e_[3 *SECRET_KEY_LEN];
  BYTE xQ_ab[SECRET_KEY_LEN];
  BYTE xQ_pw[SECRET_KEY_LEN];
  DWORD Verify;
} TOKEN_VERIFYDATA, *PTOKEN_VERIFYDATA;

Члены

e_
xQ_ab
xQ_pw
Verify

См. также

CPGetKeyParam ,CPSetKeyParam


_CONTAINER_EXTENSION

Блоб с сериализованной псевдоструктурой с расширением.

typedef struct _CONTAINER_EXTENSION {
  BOOL bCritical;
  DWORD cbExtension;
  BYTE pbExtension[1];
  char sOid[1];
} CONTAINER_EXTENSION;

Члены

bCritical
Флаг критического расширения.
cbExtension
Длина данных в pbExtension.
pbExtension
Данные.
sOid
Строка с OID-ом расширения (невыровненный указатель).

Требования:

AIX: 5/6/7 или выше.
FreeBSD: 7/8/9 или выше.
Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
Solaris: 10 или выше.
Mac OSX: 10.7/8 или выше.
iOS: 6/7 или выше.
Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
Файл описания: Прототип описан в файле WinCryptEx.h.

См. также

CPGetProvParam


_VTABLEPROVSTRUC

Структура VTABLEPROVSTRUC содержит указатели на callback функции, которые могут быть использованы функциями криптопровайдера (CSP).

    BOOL (FARPROC *ProvVerifyImage)(LPCSTR lpszImage, BYTE *pSigData);
    BYTE bSignature[72];

    // "ProvVerifyImage" has been set to "pVTable->FuncVerifyImage"
    // within the CPAcquireContext function.

    // Load the C:\Winnt40\System32\signature.sig file into the
    // bSignature buffer. During development, this file is created
    // with the Sign.exe utility.
    ...

    // Verify the signature on the C:\Winnt40\System32\Signature.dll file.
    if(RCRYPT_FAILED(ProvVerifyImage("c:\\winnt40\\system32\\signature.dll",
                                     bSignature)) {
        SetLastError(NTE_BAD_SIGNATURE);
       return CRYPT_FAILED;
    }

    // Load the DLL with the LoadLib function, then acquire pointers to
    // the member functions with the GetProcAddress function.
    ...

typedef struct _VTABLEPROVSTRUC {
  DWORD Version;
  CRYPT_VERIFY_IMAGE_A FuncVerifyImage;
  CRYPT_RETURN_HWND FuncReturnhWnd;
  DWORD dwProvType;
  BYTE * pbContextInfo;
  DWORD cbContextInfo;
  LPSTR pszProvName;
} VTABLEPROVSTRUC, *PVTABLEPROVSTRUC;

Члены

Version
DWORD значение, определяющее версию структуры. Используются три версии структуры. MicrosoftR Windows NTR версия 4.0 and MicrosoftR WindowsR 95 используют версию 1, которая содержит только три первых члена: Version, FuncVerifyImage, FuncReturnhWnd. Версия 2 используется в Windows 98. Используются первые шесть членов структуры (без pszProvName). Версия 3 используется в Windows 2000. Она включает все семь членов структуры.
FuncVerifyImage
Указатель на callback функцию, используемую для проверки ЭЦП модуля. См. Примечание.
FuncReturnhWnd
Указатель на callback функцию, возвращаемую информацию о дескрипторе окна. Дескриптор окна будет использован для взаимодействия с пользователем через MicrosoftR Win32R.
dwProvType
  • PROV_GOST_DH
  • PROV_GOST_2001_DH
  • PROV_GOST_2012_256
  • PROV_GOST_2012_512
  • PROV_RSA_FULL
  • PROV_RSA_SIG
  • PROV_DSS
  • PROV_FORTEZZA
  • PROV_MS_EXCHANGE
pbContextInfo
Только версии 2 и 3. Указатель на массив контекстной информации. Переменные pbContextInfo и cbContextInfo определяют состав передаваемой информации, используемой при вызове функции CPSetProvParam с параметром PP_CONTEXT_INFO.
cbContextInfo
Только версии 2 и 3. Значение, определяющее количество элементов в массиве pbContextInfo.
pszProvName
Только версия 3. Строка, содержащая имя провайдера.

Примечания

Указатель на структуру VTABLEPROVSTRUC доступен только во врема вызова функции CPAcquireContext. Если члены структуры необходимы для дальнейшей работы, необходимо произвести копирование значений. Скопированные указатели на функции, содержащиеся в струкруре и сами функции, могут быть использованы до тех пор пока не закрылась сессия с криптопровайдером. Все дополнительные модули (DLL), которые использует криптопровайдер могут быть подписаны, как и основной модуль. Перд загрузкой дополнительны модулей с использованием функции LoadLib, можно проверить подпись дополнительных модулей. Криптопровайдер может производить такую проверку, используя указатель на функцию FuncVerifyImage, как показано в следующем примере:


Примеры использования функций "КриптоПро CSP 4.0"

Приведенные ниже примеры демонстрируют использование основных функций криптопровайдера.

Для уменьшения размера кода примеров следующие 4 строки в них не приводятся:

 #include <stdio.h>
 #include <windows.h>
 #include <wincrypt.h>
 #include <wincryptex.h>

Во всех примерах используется функция HandleError для обработки кода ошибок, вывода сообщения и выхода из программы. В приложениях рекомендуется заменить данную функцию другой, которая позволит произвести более подробную диагностику кода ошибки.

Определение функции HandleError не приведено в примераx. Оно приводится ниже:

 void HandleError(char *s)
 {
   printf("An error occurred in running the program.\n");
   printf("%s\n",s);
   printf("Error number %x\n.",GetLastError());
   printf("Program terminating.\n");
   exit(1);
 }

  • Примеры работы с криптографическими сессиями и ключами
  • Примеры использования функций хеширования
  • Примеры использования функций шифрования
  • Примеры использования функций криптопровайдера для работы с XML-документом.
  • Примеры использования криптопровайдера совместно с функциями CAPICOM.
  • Примеры использования криптопровайдера совместно с функциями CEnroll.
  • Управление алгоритмами и параметрами RFC 4357
  • Основные отличия интерфейса КриптоПро CSP версии 4.0 от версии 3.6
  • Основные особенности отображения пользовательского UI

Примечания

Использование функций криптопровайдера возможно различными способами. Рекомендуется перед определением уровня встраивания ознакомиться с разделом "Архитектура криптографических функций в Windows".


Примеры работы с криптографическими сессиями и ключами

В данном разделе приводятся примеры, демонстрирующие использование основных функций криптопровайдера для работы с криптографическими сессиями и ключами.

  • Пример на создание ключевого контейнера и генерацию ключей
  • Пример использования функции CryptAcquireContext
  • Пример на перечисление криптопровайдеров
  • Пример на получение сессионного ключа из пароля
  • Пример на дублирование сессионного ключа
  • Пример на установку и получение сессионного ключа
  • Пример на экспортирование сессионного ключа с использованием структуры BLOB
  • Пример на экспортирование сессионного ключа с использованием сертификатами
  • Пример на закодирование и раскодирование данных
  • Пример на копирование закрытого ключа
  • Пример на работу в режиме SILENT, без окон
  • Пример экспорта закрытого ключа в блоб
  • Пример импорта закрытого ключа из блоба
  • Пример поиска контейнера, соответствующего сертификату


Пример на создание ключевого контейнера и генерацию ключей

Этот пример демонстрирует использование следующих функций
  • CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link
  • CryptDestroyKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptGenKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetProvParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetUserKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptReleaseContext в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
// Пример создания ключевого контейнера с именем, передаваемым в качестве
// параметра командной строки. Если параметр не указан, то будет создан
// контейнер с именем по умолчанию. В контейнере созданиются два ключа
// (ключ обмена и ключ подписи).
//--------------------------------------------------------------------

static HCRYPTPROV hCryptProv = 0;        // Дескриптор контекста  критографического провайдера.
static HCRYPTKEY hKey = 0;               // Дескриптор открытого/закрытого ключа.

static void CleanUp(void);
static void HandleError(char *s);

int main(int argc, char *argv[])
{
    // Объявление и инициализация переменных.
    LPSTR pszUserName;            // Буфер для хранения имени  ключевого контейнера.
    DWORD dwUserNameLen;          // Длина буфера.
    LPCSTR UserName;              // Добавленное по выбору имя пользователя
                                  // здесь будет использовано как имя
                                  // ключевого контейнера (ограничение на 100 символов).

    // Начало выполнения. Получение имени создаваемого контейнера.
    if(argc < 2)
        HandleError(" using: CreatingKeyContainer.exe <container_name>");

    UserName = argv[1];

    //  Для создания нового ключевого контейнера строка второго параметра
    //  заменяется на NULL здесь и при следующем вызове функции:
    if(CryptAcquireContext(
        &hCryptProv,               // Дескриптор CSP
        UserName,                  // Имя контейнера
        NULL,                      // Использование провайдера по умолчанию
        PROV_GOST_2012_256,        // Тип провайдера
        0))                        // Значения флагов
    {
        printf("A cryptcontext with the %s key container has been acquired.\n", UserName);
    }
    else
    {
        // Создание нового контейнера.
        if(!CryptAcquireContext(
            &hCryptProv,
            UserName,
            NULL,
            PROV_GOST_2012_256,
            CRYPT_NEWKEYSET))
        {
             HandleError("Could not create a new key container.\n");
        }
        printf("A new key container has been created.\n");
    }

    // Криптографический контекст с ключевым контейнером доступен. Получение
    // имени ключевого контейнера.
    if(!CryptGetProvParam(
        hCryptProv,               // Дескриптор CSP
        PP_CONTAINER,             // Получение имени ключевого контейнера
        NULL,                     // Указатель на имя ключевого контейнера
        &dwUserNameLen,           // Длина имени
        0))
    {
        // Ошибка получении имени ключевого контейнера
        HandleError("error occurred getting the key container name.");
    }

    // Лучше использовать auto_ptr:
    //std::auto_ptr<char> aptrUserName(new char[dwUserNameLen+1]);
    //szUserName = aptrUserName.get();
    pszUserName=(char *)malloc((dwUserNameLen+1));

    if(!CryptGetProvParam(
        hCryptProv,               // Дескриптор CSP
        PP_CONTAINER,             // Получение имени ключевого контейнера
        (LPBYTE)pszUserName,      // Указатель на имя ключевого контейнера
        &dwUserNameLen,           // Длина имени
        0))
    {
        // Ошибка получении имени ключевого контейнера
        free(pszUserName);
        HandleError("error occurred getting the key container name.");
    }

    printf("A crypto context has been acquired and \n");
    printf("The name on the key container is %s\n\n", pszUserName);
    free(pszUserName);

    // Контекст с ключевым контейнером доступен,
    // попытка получения дескриптора ключа подписи
    if(CryptGetUserKey(
        hCryptProv,                     // Дескриптор CSP
        AT_SIGNATURE,                   // Спецификация ключа
        &hKey))                         // Дескриптор ключа
    {
        printf("A signature key is available.\n");
    }
    else
    {
        printf("No signature key is available.\n");

        // Ошибка в том, что контейнер не содержит ключа.
        if(!(GetLastError() == (DWORD)NTE_NO_KEY))
            HandleError("An error other than NTE_NO_KEY getting signature key.\n");

        // Создание подписанной ключевой пары.
        printf("The signature key does not exist.\n");
        printf("Creating a signature key pair...\n");

        if(!CryptGenKey(
            hCryptProv,
            AT_SIGNATURE,
            0,
            &hKey))
        {
            HandleError("Error occurred creating a signature key.\n");
        }
        printf("Created a signature key pair.\n");

    }

    // Получение ключа обмена: AT_KEYEXCHANGE
    if(CryptGetUserKey(
        hCryptProv,
        AT_KEYEXCHANGE,
        &hKey))
    {
        printf("An exchange key exists. \n");
    }
    else
    {
        printf("No exchange key is available.\n");
    }

    CleanUp();

    printf("Everything is okay. A signature key\n");
    printf("pair and an exchange key exist in\n");
    printf("the %s key container.\n", UserName);

    return 0;
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Пример использования функции CryptAcquireContext

Этот пример демонстрирует использование следующих функций
  • CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link
  • CryptReleaseContext в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetProvParam в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
// Пример кода, использующего CryptAcquireContext.
//--------------------------------------------------------------------

#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

static HCRYPTPROV hCryptProv = 0;
static HCRYPTKEY hKey = 0;

static void CleanUp(void);
static void HandleError(char *s);

int main(int argc, char *argv[])
{
    // Объявление и инициализация переменных.
    BYTE pbData[MAX_CONTAINER_NAME_LEN+1];
    DWORD cbData;
    BOOL bSilent = FALSE;

    // Флаг режима без окон
    if (argc > 1 && strcmp(argv[1], "-silent") == 0)
        bSilent = TRUE;
    printf("Mode: %s\n", bSilent ? "SILENT" : "NORMAL");

    // Получение дескриптора криптопровайдера.
    if(!CryptAcquireContext(
        &hCryptProv,
        CONTAINER,
        NULL,
        PROV_GOST_2012_256,
        0))
    {
        if(!(GetLastError() == 0x80090016 ))
        {
            SetLastError(0x80090016);
            HandleError("A general error occurred running CryptAcquireContext");
        }

        printf(" The default key container does not exist.\n");
        printf(" Create a default container and generate keys \n");
        printf(" Using the code in \n");
        printf("  Example C Program: Creating a Key Container and Generating Keys \n");
        printf("  Before running this program. \n");

        CleanUp();
        exit(0);
    }
    printf("CryptAcquireContext succeeded.\n");

    // Чтение имени CSP.
    cbData = MAX_CONTAINER_NAME_LEN;
    if(!CryptGetProvParam(
        hCryptProv,
        PP_NAME,
        NULL,
        &cbData,
        0))
    {
        HandleError("Error reading CSP name. \n");
    }

    if(cbData > MAX_CONTAINER_NAME_LEN)
        HandleError("CSP name length is too long");

    pbData[MAX_CONTAINER_NAME_LEN] = 0;
    if(!CryptGetProvParam(
        hCryptProv,
        PP_NAME,
        pbData,
        &cbData,
        0))
    {
        HandleError("Error reading CSP name. \n");
    }

    printf("CryptGetProvParam succeeded.\n");
    printf("Provider name: %s\n", pbData);

    // Чтение имени ключевого контейнера.
    cbData = MAX_CONTAINER_NAME_LEN;
    if(!CryptGetProvParam(
        hCryptProv,
        PP_CONTAINER,
        pbData,
        &cbData,
        0))
    {
        HandleError("Error reading key container name. \n");
    }
    if(cbData > MAX_CONTAINER_NAME_LEN)
        HandleError("Container name length is too long");

    if(!CryptGetProvParam(
        hCryptProv,
        PP_CONTAINER,
        pbData,
        &cbData,
        0))
    {
        HandleError("Error reading key container name. \n");
    }

    printf("CryptGetProvParam succeeded. \n");
    printf("Key Container name: %s\n", pbData);

    // Выполнение криптографических операций.

    //  Увеличение счетчика ссылок на криптопровайдер. Когда счетчик ссылок на
    //  криптопровайдер становится больше 1, CryptReleaseContext уменьшает
    //  счетчик ссылок, но не освобождает криптопровайдер.

    if(!CryptContextAddRef(
        hCryptProv,
        NULL,
        0))
    {
        HandleError("Error during CryptContextAddRef!\n");
    }
    printf("CryptContextAddRef succeeded. \n");

    //  Счетчик ссылок на hCryptProv сейчас больше 1. Первый вызов
    //  функции CryptReleaseContext не освободит дескриптор криптопровайдера.

    //  Однократное освобождение контекста.
    if(!CryptReleaseContext(hCryptProv, 0))
    {
        HandleError("Error during CryptReleaseContext! #1");
    }
    printf("The first call to CryptReleaseContext succeeded. \n");

    // Повторное освобождение дескриптора криптопровайдера.
    if(!CryptReleaseContext(hCryptProv, 0))
    {
        HandleError("Error during CryptReleaseContext! #2");
    }
    printf("The second call to CryptReleaseContext succeeded. \n");

    // Получение дескриптора криптопровайдера и
    // создание ключевого контейнера с именем "KC1_test".
    if(!CryptAcquireContext(
        &hCryptProv,
#ifdef _WIN32
        "\\\\.\\REGISTRY\\KC1_test",
#else
        "\\\\.\\HDIMAGE\\KC1_test",
#endif
        NULL,
        PROV_GOST_2012_256,
        CRYPT_NEWKEYSET | (bSilent ? CRYPT_SILENT : 0)))
    {
        HandleError("Error during CryptAcquireContext for a new key "
                    "container. A container with this name probably "
                    "already exists");
    }
    printf("CryptAcquireContext (CRYPT_NEWKEYSET) succeeded. \n");

    // begin Особенность КриптоПро CSP
    // Особенностью КриптоПро CSP является то, что криптопровайдер
    // физически не создает (записывает) контейнер, если в нем
    // нет закрытых ключей. Поэтому необходимо создать ключ.
    if(!CryptGenKey(
        hCryptProv,
        AT_SIGNATURE,
        0,
        &hKey))
    {
        HandleError("Error occurred creating a signature key.\n");
    }
    printf("Created a signature key pair.\n");
    // end Особенность КриптоПро CSP

    // Выполнение криптографических операций.

    // Освобождение дескриптора криптопровайдера и ключевого контейнера KC1.
    if(!CryptReleaseContext(hCryptProv, 0))
    {
        HandleError("Error during CryptReleaseContext!\n");
    }
    printf("CryptReleaseContext succeeded. \n");
    hCryptProv = 0;
    hKey = 0;

    // Получение дескриптора криптопровайдера, используя новый ключевой контейнер.
    // Замечание: Этот ключевой контейнер будет пустым до тех пор, пока ключи
    // не будут явно созданы с помощью функции CryptGenKey.
    if(!CryptAcquireContext(
        &hCryptProv,
        "KC1_test",
        NULL,
        PROV_GOST_2012_256,
        0))
    {
        HandleError("Error during CryptAcquireContext!\n");
    }
    printf("Acquired the key set just created. \n");

    // Выполнение криптографических операций.

    // Освобождение дескриптора криптопровайдера и ключевого контейнера KC1.
    if(!CryptReleaseContext(hCryptProv, 0))
    {
        HandleError("Error during CryptReleaseContext!\n");
    }
    printf("CryptReleaseContext succeeded. \n");
    hCryptProv = 0;

    // Для повторного испоьзования этого примера необходимо удалить созданный
    // ключей контейнер с именем "КС1". Контейнер можно удалить при помощи
    // контрольной панели КриптоПро CSP или следующим образом:
    if(!CryptAcquireContext(
        &hCryptProv,
        "KC1_test",
        NULL,
        PROV_GOST_2012_256,
        CRYPT_DELETEKEYSET))
    {
        HandleError("Error during CryptAcquireContext(CRYPT_DELETEKEYSET)!\n");
    }
    printf("CryptAcquireContext (CRYPT_DELETEKEYSET) succeeded. \n");

    CleanUp();
    return 0;
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Пример на перечисление криптопровайдеров

Этот пример демонстрирует использование следующих функций
  • CryptEnumProviderTypes в MS CryptoAPI 2.0 World Wide Web link
  • CryptEnumProviders в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetDefaultProvider в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetProvParam в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
//  В примере используются функции CryptEnumProviderTypes, CryptEnumProviders,
//  CryptGetDefaultProvider и CryptGetProvParam.
//  Большинство из этих функций доступны только для версий Windows 2000
//  и старше.
//
//  Для корректной работы данного примера необходимо предварительно создать
//  контейнер с именем "OUR_Container" (например, при помощи программы
//  CreatingKeyContainer).
//  Замечание: под win32 рекомендуется использовать _s аналоги CRT функций.
//--------------------------------------------------------------------

static void HandleError(char *s);
static void CleanUp(void);

static HCRYPTPROV  hProv = 0;         // Дескриптор CSP
static LPTSTR      pszName = NULL;
static LPTSTR      pbProvName = NULL;

int main(void)
{

    //--------------------------------------------------------------------
    //  Объявление и инициализация переменных.

    DWORD       dwType;
    DWORD       cbName;
    DWORD       dwIndex = 0;
    BYTE        *ptr = NULL;
    ALG_ID      aiAlgid;
    DWORD       dwBits;
    DWORD       dwNameLen;
    CHAR        szName[NAME_LENGTH]; // Распределены динамически
    BYTE        pbData[1024];// Распределены динамически
    DWORD       cbData=1024;
    DWORD       dwIncrement = sizeof(DWORD);
    DWORD       dwFlags = CRYPT_FIRST;
    CHAR        *pszAlgType = NULL;
    BOOL        fMore = TRUE;
    DWORD       cbProvName;

    //   Печать заголовка перечисления типов провайдеров.
    printf("\n          Listing Available Provider Types.\n");
    printf("Provider type      Provider Type Name\n");
    printf("_____________    _____________________________________\n");

    // Цикл по перечисляемым типам провайдеров.
    dwIndex = 0;
    while(CryptEnumProviderTypes(
        dwIndex,     // in -- dwIndex
        NULL,        // in -- pdwReserved- устанавливается в NULL
        0,           // in -- dwFlags -- устанавливается в ноль
        &dwType,     // out -- pdwProvType
        NULL,        // out -- pszProvName -- NULL при первом вызове
        &cbName      // in, out -- pcbProvName
        ))
    {
        //  cbName - длина имени следующего типа провайдера.
        //  Распределение памяти в буфере для восстановления этого имени.
        pszName = (LPTSTR)malloc(cbName);
        if(!pszName)
            HandleError("ERROR - malloc failed!");

        memset(pszName, 0, cbName);

        //--------------------------------------------------------------------
        //  Получение имени типа провайдера.

        if(CryptEnumProviderTypes(
            dwIndex++,
            NULL,
            0,
            &dwType,
            pszName,
            &cbName))
        {
            printf ("     %4.0d        %s\n",dwType, pszName);
        }
        else
        {
            HandleError("ERROR - CryptEnumProviders");
        }
    }

    //   Печать заголовка перечисления провайдеров.
    printf("\n\n          Listing Available Providers.\n");
    printf("Provider type      Provider Name\n");
    printf("_____________    _____________________________________\n");

    // Цикл по перечисляемым провайдерам.
    dwIndex = 0;
    while(CryptEnumProviders(
        dwIndex,     // in -- dwIndex
        NULL,        // in -- pdwReserved- устанавливается в NULL
        0,           // in -- dwFlags -- устанавливается в ноль
        &dwType,     // out -- pdwProvType
        NULL,        // out -- pszProvName -- NULL при первом вызове
        &cbName      // in, out -- pcbProvName
        ))
    {
        //  cbName - длина имени следующего провайдера.
        //  Распределение памяти в буфере для восстановления этого имени.
        pszName = (LPTSTR)malloc(cbName);
        if(!pszName)
            HandleError("ERROR - malloc failed!");

        memset(pszName, 0, cbName);

        //  Получение имени провайдера.
        if(CryptEnumProviders(
            dwIndex++,
            NULL,
            0,
            &dwType,
            pszName,
            &cbName     // pcbProvName -- длина pszName
            ))
        {
            printf ("     %4.0d        %s\n",dwType, pszName);
        }
        else
        {
            HandleError("ERROR - CryptEnumProviders");
        }

    } // Конец цикла while

    printf("\n\nProvider types and provider names have been listed.\n");

    // Получение имени CSP, определенного для компьютера по умолчанию.

    // Получение длины имени провайдера по умолчанию.
    if(!CryptGetDefaultProvider(
        PROV_GOST_2012_256,
        NULL,
        CRYPT_MACHINE_DEFAULT,
        NULL,
        &cbProvName))
    {
        HandleError("Error getting the length of the default provider name.");
    }

    // Распределение локальной памяти под имя провайдера по умолчанию.

    pbProvName = (LPTSTR)malloc(cbProvName);
    if(!pbProvName)
        HandleError("Error during memory allocation for provider name.");

    memset(pbProvName, 0, cbProvName);

    // Получение имени провайдера по умолчанию.
    if(CryptGetDefaultProvider(
        PROV_GOST_2012_256,
        NULL,
        CRYPT_MACHINE_DEFAULT,
        pbProvName,
        &cbProvName))
    {
        printf("The default provider name is %s\n\n",pbProvName);
    }
    else
    {
        HandleError("Getting the name of the provider failed.");
    }

    //-----------------------------------------------------
    //  Получение криптографического контекста.

    if(!CryptAcquireContext(
        &hProv,
        NULL,
        NULL,
        PROV_GOST_2012_256,
        CRYPT_VERIFYCONTEXT))
    {
        HandleError("Error during CryptAcquireContext!");
    }

    //------------------------------------------------------
    // Перечисление поддерживаемых алгоритмов.

    //------------------------------------------------------
    // Печать заголовка таблицы, содержащей информацию об алгоритмах
    printf("\n               Enumerating the supported algorithms\n\n");
    printf("     Algid      Bits      Type        Name         Algorithm\n");
    printf("                                     Length          Name\n");
    printf("    ________________________________________________________\n");

    while(fMore)
    {
        //------------------------------------------------------
        // Извлечение информации об алгоритме.

        if(CryptGetProvParam(hProv, PP_ENUMALGS, pbData, &cbData, dwFlags))
        {
            //-----------------------------------------------------------
            // Извлечение информации об алгоритме из буфера 'pbData'.

            dwFlags=0;
            ptr = pbData;
            aiAlgid = *(ALG_ID *)ptr;
            ptr += sizeof(ALG_ID);
            dwBits = *(DWORD *)ptr;
            ptr += dwIncrement;
            dwNameLen = *(DWORD *)ptr;
            ptr += dwIncrement;
            //strncpy_s(szName, NAME_LENGTH, (char *) ptr, dwNameLen);
            strncpy(szName, (char *) ptr, dwNameLen);
            // Определение типа алгоритма.

            switch(GET_ALG_CLASS(aiAlgid)) {
                case ALG_CLASS_DATA_ENCRYPT: pszAlgType = "Encrypt  ";
                    break;
                case ALG_CLASS_HASH:         pszAlgType = "Hash     ";
                    break;
                case ALG_CLASS_KEY_EXCHANGE: pszAlgType = "Exchange ";
                    break;
                case ALG_CLASS_SIGNATURE:    pszAlgType = "Signature";
                    break;
                default:                     pszAlgType = "Unknown  ";
            }

            // Печать информации об алгоритме.
            printf("    %8.8xh    %-4d    %s     %-2d          %s\n",
                aiAlgid, dwBits, pszAlgType, dwNameLen, szName);
        }
        else
            fMore = FALSE;
    }

    if(GetLastError() == ERROR_NO_MORE_ITEMS)
    {
        printf("\nThe program completed without error.\n");
    }
    else
    {
        HandleError("Error reading algorithm!");
    }

    CleanUp();
    return 0;
}

void CleanUp(void)
{
    // Освобождение дескриптора провайдера.
    if(hProv)
        CryptReleaseContext(hProv, 0);
    if(pszName)
        free(pszName);
    if(pbProvName)
        free(pbProvName);
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Пример на получение сессионного ключа из пароля

Этот пример демонстрирует использование следующих функций
  • CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link
  • CryptCreateHash в MS CryptoAPI 2.0 World Wide Web link
  • CryptHashData в MS CryptoAPI 2.0 World Wide Web link
  • CryptDeriveKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptReleaseContext в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
// Пример создания сессионного ключа, основанного на хеше, рассчитанного
// из пароля пользователя. Пароль вводится в процессе работы программы.
// Замечание: под win32 рекомендуется использовать _s аналоги CRT функций.
//--------------------------------------------------------------------

#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
static void HandleError(char *s);
static void CleanUp(void);

static HCRYPTPROV hCryptProv = 0;
static HCRYPTKEY hKey = 0;
static HCRYPTHASH hHash = 0;

int main(void)
{
    //--------------------------------------------------------------------
    //  Пароль из которого будет получен сессионный ключ.

    CHAR szPassword[] = "123456\0";
    DWORD dwLength;

    dwLength = (DWORD)strlen(szPassword);

    //--------------------------------------------------------------------
    // Получение дескриптора контекста криптографического провайдера.

    if(CryptAcquireContext(
        &hCryptProv,
        NULL,
        NULL,
        PROV_GOST_2012_256,
        CRYPT_VERIFYCONTEXT))
    {
        printf("A context has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptAcquireContext!");
    }
    //--------------------------------------------------------------------
    // Создание пустого объекта хеширования.

    if(CryptCreateHash(
        hCryptProv,
        CALG_GR3411_2012_256,
        0,
        0,
        &hHash))
    {
        printf("An empty hash object has been created. \n");
    }
    else
    {
        HandleError("Error during CryptCreateHash!");
    }
    //--------------------------------------------------------------------
    // Хеширование строки пароля.

    if(CryptHashData(
        hHash,
        (BYTE *)szPassword,
        dwLength,
        0))
    {
        printf("The password has been hashed. \n");
    }
    else
    {
        HandleError("Error during CryptHashData!");
    }
    //--------------------------------------------------------------------
    // Создание сессионного ключа, основанного на хеше, полученного из пароля.

    if(CryptDeriveKey(
        hCryptProv,
        CALG_G28147,
        hHash,
        CRYPT_EXPORTABLE,
        &hKey))
    {
        printf("The key has been derived. \n");
    }
    else
    {
        HandleError("Error during CryptDeriveKey!");
    }

    CleanUp();

    printf("The program to derive a key completed without error. \n");

    return 0;
}

void CleanUp(void)
{
    if(hHash)
        CryptDestroyHash(hHash);

    // Уничтожение сессионного ключа.
    if(hKey)
        CryptDestroyKey(hKey);

    // Освобождение дескриптора провайдера.
    if(hCryptProv)
        CryptReleaseContext(hCryptProv, 0);
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Пример на дублирование сессионного ключа

Этот пример демонстрирует использование следующих функций
  • CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link
  • CryptGenKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptDuplicateKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptSetKeyParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptGenRandom в MS CryptoAPI 2.0 World Wide Web link
  • CryptDestroyKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptReleaseContext в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
//--------------------------------------------------------------------
static void HandleError(char *s);
static void CleanUp(void);

static HCRYPTPROV   hCryptProv = 0;
static HCRYPTKEY    hOriginalKey = 0;
static HCRYPTKEY    hDuplicateKey = 0;

int main(void)
{
    DWORD        dwMode;
    BYTE         pbData[16];

    printf("This program creates a session key and duplicates \n");
    printf("that key. Next, parameters are added to the original \n");
    printf("key. Finally, both keys are destroyed. \n\n");

    // Получение дескриптора контекста криптографического провайдера.
    if(CryptAcquireContext(
        &hCryptProv,
        NULL,
        NULL,
        PROV_GOST_2012_256,
        CRYPT_VERIFYCONTEXT))
    {
        printf("CryptAcquireContext succeeded. \n");
    }
    else
    {
        HandleError("Error during CryptAcquireContext!\n");
    }

    // Генерация ключа.
    if(CryptGenKey(
        hCryptProv,
        CALG_G28147,
        0,
        &hOriginalKey))
    {
        printf("Original session key is created. \n");
    }
    else
    {
        HandleError("ERROR - CryptGenKey.");
    }

    // Дублирование ключа.
    if(CryptDuplicateKey(
        hOriginalKey,
        NULL,
        0,
        &hDuplicateKey))
    {
        printf("The session key has been duplicated. \n");
    }
    else
    {
        HandleError("ERROR - CryptDuplicateKey");
    }

    //  Установка дополнительных параметров исходного ключа.
    //  В первую очередь, установка режима шифрования.
    dwMode = CRYPT_MODE_ECB;
    if(CryptSetKeyParam(
        hOriginalKey,
        KP_MODE,
        (BYTE*)&dwMode,
        0))
    {
        printf("Key Parameters set. \n");
    }
    else
    {
        HandleError("Error during CryptSetKeyParam.");
    }

    // Генерация случайного вектора инициализации.
    if(CryptGenRandom(
        hCryptProv,
        8,
        pbData))
    {
        printf("Random sequence generated. \n");
    }
    else
    {
        HandleError("Error during CryptGenRandom.");
    }

    // Установка вектора инициализации.
    if(CryptSetKeyParam(
        hOriginalKey,
        KP_IV,
        pbData,
        0))
    {
        printf("Parameter set with random sequence as initialization vector. \n");
    }
    else
    {
        HandleError("Error during CryptSetKeyParam.");
    }

    CleanUp();

    printf("\nThe program ran to completion without error. \n");
    return 0;
}

void CleanUp(void)
{
    if(hOriginalKey)
        CryptDestroyKey(hOriginalKey);

    if(hDuplicateKey)
        CryptDestroyKey(hDuplicateKey);

    if(hCryptProv)
        CryptReleaseContext(hCryptProv, 0);
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Пример на установку и получение сессионного ключа

Этот пример демонстрирует использование следующих функций
  • CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link
  • CryptGenRandom в MS CryptoAPI 2.0 World Wide Web link
  • CryptGenKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetKeyParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptSetKeyParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptGenRandom в MS CryptoAPI 2.0 World Wide Web link
  • CryptDestroyKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptReleaseContext в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
// В данном примере осуществляется создание случайного сессионного
// ключа шифрования и изменение одного из его параметров (вектора
// инициализации).
//---------------------------------------------------------------------

static void HandleError(char *s);
static void CleanUp(void);

static HCRYPTPROV hProv = 0;
static HCRYPTKEY hKey = 0;

int main(void)
{
    DWORD dwMode;
    BYTE pbData[16];
    BYTE pbRandomData[8];
    DWORD dwCount;
    DWORD i;

    //--------------------------------------------------------------------
    // Получение дескриптора контекста криптографического параметра.

    if(!CryptAcquireContext(
        &hProv,
        NULL,
        NULL,
        PROV_GOST_2012_256,
        CRYPT_VERIFYCONTEXT))
    {
        HandleError("Error during CryptAcquireContext.");
    }

    //--------------------------------------------------------------
    //  Генерация восьми байтов случайных данных в pbRandomData.

    if(CryptGenRandom(
        hProv,
        8,
        pbRandomData))
    {
        printf("Eight bytes of random data have been generated.\n");
    }
    else
    {
        HandleError("Random bytes were not correctly generated.");
    }
    // Создание случайного сессионного ключа блочного шифрования.

    if(!CryptGenKey(
        hProv,
        CALG_G28147,
        CRYPT_EXPORTABLE,
        &hKey))
    {
        HandleError("Error during CryptGenKey.");
    }

    //--------------------------------------------------------------------
    // Чтение режима шифрования.

    dwCount = sizeof(DWORD);
    if(CryptGetKeyParam(
        hKey,
        KP_MODE,
        (BYTE*)&dwMode,
        &dwCount,
        0))
    {
        //---------------------------------------------------------------
        // Печать режима шифрования.

        printf("Default cipher mode: %d\n", dwMode);

    }
    else
    {
        HandleError("Error during CryptGetKeyParam.");
    }

    //---------------------------------------------------------------
    // Чтение вектора инициализации.

    //-------------------------------------------------------------
    //  Получение длины вектора инициализации.

    if(!CryptGetKeyParam(
        hKey,
        KP_IV,
        NULL,
        &dwCount,
        0))
    {
        HandleError("Error getting the IV length");
    }

    //--------------------------------------------------------------
    // Получение IV - вектора инициализации.

    if(CryptGetKeyParam(
        hKey,
        KP_IV,
        pbData,
        &dwCount,
        0))
    {
        //---------------------------------------------------------
        // Печать вектора инициализации.
        printf("Default IV:");
        for(i=0;i<dwCount;i++)
            printf("%2.2x ",pbData[i]);
        printf("\n");
    }
    else
    {
        HandleError("Error getting the IV.");
    }

    //-------------------------------------------------------------
    //  Переустановка вектора инициализации.

    if(CryptSetKeyParam(
        hKey,
        KP_IV,
        pbRandomData,
        0))
    {
        printf("New intialization vector is set.\n");
    }
    else
    {
        HandleError("The new IV was not set.");
    }
    //---------------------------------------------------------------
    // Чтение нового вектора инициализации.

    //-------------------------------------------------------------
    //  Получение длины нового вектора инициализации.

    if(!CryptGetKeyParam(
        hKey,
        KP_IV,
        NULL,
        &dwCount,
        0))
    {
        HandleError("Error getting the IV length");
    }

    //--------------------------------------------------------------
    // Получение IV - вектора инициализации.

    if(CryptGetKeyParam(
        hKey,
        KP_IV,
        pbData,
        &dwCount,
        0))
    {
        //---------------------------------------------------------
        // Печать вектора инициализации.
        printf("RE-set IV:");
        for(i=0;i<dwCount;i++)
            printf("%2.2x ",pbData[i]);
        printf("\n");
    }
    else
    {
        HandleError("Error getting the IV.");
    }

    CleanUp();

    printf("\nProgram completing without error.\n\n");

    return 0;
}

void CleanUp(void)
{
    if(hKey)
        CryptDestroyKey(hKey);

    if(hProv)
        CryptReleaseContext(hProv, 0);
}
// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Пример на экспортирование сессионного ключа с использованием структуры BLOB

Этот пример демонстрирует использование следующих функций
  • CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetUserKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptGenKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptExportKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptImportKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetKeyParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptDestroyKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptReleaseContext в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
// В данном примере осуществляется экспортирование сессионного ключа
// при помощи структуры BLOB.
// Для корректной работы этой программы необходимо создать два
// контейнера: получателя (с именем "Responder") и отправителя (c именем
// "Sender").
//--------------------------------------------------------------------

static void HandleError(char *s);
static void CleanUp(void);

static HCRYPTPROV hProvResponder = 0;     // Дескриптор CSP получателя
static HCRYPTPROV hProvSender = 0;        // Дескриптор CSP отправителя
static HCRYPTKEY hSessionKey = 0;         // Дескриптор сессионного ключа
static HCRYPTKEY hAgreeKey = 0;           // Дескриптор ключа согласования
static HCRYPTKEY hResponderKey = 0;       // Дескриптор открытого ключа получателя
static HCRYPTKEY hSenderKey = 0;          // Дескриптор открытого ключа отправителя
static BYTE *pbKeyBlobSender = NULL;       // Указатель на ключевой BLOB отправителя
static BYTE *pbKeyBlobResponder = NULL;   // Указатель на ключевой BLOB получателя
static BYTE *pbKeyBlobSimple = NULL;      // Указатель на сессионный ключевой BLOB

int main(void)
{

    DWORD dwBlobLenSender;         // Длина ключевого BLOBа отправителя
    DWORD dwBlobLenResponder;      // Длина ключевого BLOBа получателя
    DWORD dwBlobLenSimple;         // Длина сессионного ключевого BLOBа

    //--------------------------------------------------------------------
    // На стороне получателя: отправляем открытый ключ отправителю
    //--------------------------------------------------------------------

    //--------------------------------------------------------------------
    // Получение дескриптора контейнера получателя с именем "Responder",
    // находящегося в рамках провайдера.

    if(CryptAcquireContext(
        &hProvResponder,
        "Responder",
        NULL,
        PROV_GOST_2012_256,
        0))
    {
        printf("The key container \"Responder\" has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptAcquireContext.");
    }
    //--------------------------------------------------------------------
    // Получение дескриптора открытого ключа получателя.

    if(CryptGetUserKey(
        hProvResponder,
        AT_KEYEXCHANGE,
        &hResponderKey))
    {
        printf("The responder public key has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptGetUserKey public key.");
    }

    //--------------------------------------------------------------------
    // pbKeyBlobResponder - открытый ключ получателя, передаем его оправителю.
    //
    //--------------------------------------------------------------------

    //--------------------------------------------------------------------
    // Определение размера BLOBа открытого ключа и распределение памяти.

    if(CryptExportKey(
        hResponderKey,
        0,
        PUBLICKEYBLOB,
        0,
        NULL,
        &dwBlobLenResponder))
    {
        printf("Size of the BLOB for the responder public key determined. \n");
    }
    else
    {
        HandleError("Error computing BLOB length.");
    }

    pbKeyBlobResponder = (BYTE*)malloc(dwBlobLenResponder);

    if(pbKeyBlobResponder)
    {
        printf("Memory has been allocated for the BLOB. \n");
    }
    else
    {
        HandleError("Out of memory. \n");
    }
    //--------------------------------------------------------------------
    // Экспортирование открытого ключа получателя в BLOB открытого ключа.

    if(CryptExportKey(
        hResponderKey,
        0,
        PUBLICKEYBLOB,
        0,
        pbKeyBlobResponder,
        &dwBlobLenResponder))
    {
        printf("Contents have been written to the BLOB. \n");
    }
    else
    {
        HandleError("Error during CryptExportKey.");
    }

    //--------------------------------------------------------------------
    // На стороне отправителя: отправляем открытый ключ получателю.
    //--------------------------------------------------------------------

    // Получение дескриптора контейнера отправителя с именем "Sender",
    // находящегося в рамках провайдера.

    if(CryptAcquireContext(
        &hProvSender,
        "Sender",
        NULL,
        PROV_GOST_2012_256,
        0))
    {
        printf("The key container \"Sender\" has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptAcquireContext.");
    }
    //--------------------------------------------------------------------
    // Получение дескриптора открытого ключа отправителя.

    if(CryptGetUserKey(
        hProvSender,
        AT_KEYEXCHANGE,
        &hSenderKey))
    {
        printf("The sender public key has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptGetUserKey public key.");
    }

    //--------------------------------------------------------------------
    // pbKeyBlobSender - открытый ключ отправителя, передаем его получателю.
    //
    //--------------------------------------------------------------------

    //--------------------------------------------------------------------
    // Определение размера BLOBа открытого ключа и распределение памяти.

    if(CryptExportKey(
        hSenderKey,
        0,
        PUBLICKEYBLOB,
        0,
        NULL,
        &dwBlobLenSender))
    {
        printf("Size of the BLOB for the sender public key determined. \n");
    }
    else
    {
        HandleError("Error computing BLOB length.");
    }

    pbKeyBlobSender = (BYTE*)malloc(dwBlobLenSender);

    if(pbKeyBlobSender)
    {
        printf("Memory has been allocated for the BLOB. \n");
    }
    else
    {
        HandleError("Out of memory. \n");
    }
    //--------------------------------------------------------------------
    // Экспортирование открытого ключа отправителя в BLOB открытого ключа.

    if(CryptExportKey(
        hSenderKey,
        0,
        PUBLICKEYBLOB,
        0,
        pbKeyBlobSender,
        &dwBlobLenSender))
    {
        printf("Contents have been written to the BLOB. \n");
    }
    else
    {
        HandleError("Error during CryptExportKey.");
    }
    //--------------------------------------------------------------------
    // Получение ключа согласования импортом открытого ключа получателя
    // на открытом ключе отправителя.

    if(CryptImportKey(
        hProvSender,
        pbKeyBlobResponder,
        dwBlobLenResponder,
        hSenderKey,
        0,
        &hAgreeKey))
    {
        printf("The sender public key has been imported. \n");
    }
    else
    {
        HandleError("Error during CryptImportKey public key.");
    }

    //--------------------------------------------------------------------
    // Генерация сессионного ключа.

    if(CryptGenKey(
        hProvSender,
        CALG_G28147,
        CRYPT_EXPORTABLE,
        &hSessionKey))
    {
        printf("Original session key is created. \n");
    }
    else
    {
        HandleError("ERROR -- CryptGenKey.");
    }

    //--------------------------------------------------------------------
    // pbKeyBlobSimple - зашифрованный сессионный ключ, передаем его получателю.
    //
    //--------------------------------------------------------------------

    //--------------------------------------------------------------------
    // Определение размера BLOBа сессионного ключа и распределение памяти.

    if(CryptExportKey(
        hSessionKey,
        hAgreeKey,
        SIMPLEBLOB,
        0,
        NULL,
        &dwBlobLenSimple))
    {
        printf("Size of the BLOB for the sender session key determined. \n");
    }
    else
    {
        HandleError("Error computing BLOB length.");
    }

    pbKeyBlobSimple = (BYTE*)malloc(dwBlobLenSimple);

    if(pbKeyBlobSimple)
    {
        printf("Memory has been allocated for the BLOB. \n");
    }
    else
    {
        HandleError("Out of memory. \n");
    }
    //--------------------------------------------------------------------
    // Шифрование ключа согласования на сессионном ключе.

    if(CryptExportKey(
        hSessionKey,
        hAgreeKey,
        SIMPLEBLOB,
        0,
        pbKeyBlobSimple,
        &dwBlobLenSimple))
    {
        printf("Contents have been written to the BLOB. \n");
    }
    else
    {
        HandleError("Error during CryptExportKey.");
    }

    //--------------------------------------------------------------------
    // На стороне получателя: получили зашифрованный сессионный ключ:
    // pbKeyBlobSimple, получили открытый ключ: pbKeyBlobSender.
    //--------------------------------------------------------------------

    // Получение ключа согласования импортом открытого ключа отправителя
    // на открытом ключе получателя.

    if(CryptImportKey(
        hProvResponder,
        pbKeyBlobSender,
        dwBlobLenSender,
        hResponderKey,
        0,
        &hAgreeKey))
    {
        printf("The responder public key has been imported. \n");
    }
    else
    {
        HandleError("Error during CryptImportKey public key.");
    }

    // Получение сессионного ключа импортом зашифрованного сессионного ключа
    // на ключе Agree.

    if(CryptImportKey(
        hProvResponder,
        pbKeyBlobSimple,
        dwBlobLenSimple,
        hAgreeKey,
        0,
        &hSessionKey))
    {
        printf("The session key has been imported. \n");
    }
    else
    {
        HandleError("Error during CryptImportKey session key.");
    }

    CleanUp();

    printf("The program ran to completion without error. \n");
    return 0;
}

void CleanUp(void)
{
    free(pbKeyBlobSender);
    free(pbKeyBlobResponder);
    free(pbKeyBlobSimple);

    // Уничтожение сессионного ключа.
    if(hSessionKey)
        CryptDestroyKey(hSessionKey);

    // Уничтожение ключа согласования.
    if(hAgreeKey)
        CryptDestroyKey(hAgreeKey);

    // Уничтожение дескриптора открытого ключа получателя.
    if(hResponderKey)
        CryptDestroyKey(hResponderKey);

    // Уничтожение дескриптора открытого ключа отправителя.
    if(hSenderKey)
        CryptDestroyKey(hSenderKey);

    // Освобождение дескриптора провайдера.
    if(hProvResponder)
        CryptReleaseContext(hProvResponder, 0);
    if(hProvSender)
        CryptReleaseContext(hProvSender, 0);
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Пример на экспортирование сессионного ключа с использованием сертификатами

Этот пример демонстрирует использование следующих функций
  • CertOpenStore в MS CryptoAPI 2.0 World Wide Web link
  • CertFindCertificateInStore в MS CryptoAPI 2.0 World Wide Web link
  • CryptAcquireCertificatePrivateKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptImportPublicKeyInfoEx в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetUserKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptGenKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetKeyParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptEncrypt в MS CryptoAPI 2.0 World Wide Web link
  • CryptDecrypt в MS CryptoAPI 2.0 World Wide Web link
  • CryptDestroyKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptReleaseContext в MS CryptoAPI 2.0 World Wide Web link
  • CertCloseStore в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
// В данном примере осуществляется экспортирование сессионного ключа
// при помощи сертификатов получателя и отправителя.
// Для корректной работы этой программы необходимо создать два
// сертификата и добавить их в хранилище сертификатов MY: получателя
// (с именем, содержащим "Responder") и отправителя (c именем, содержащим
// "Sender").
//--------------------------------------------------------------------

static void HandleError(char *s);
static void CleanUp(BOOL);

static HCERTSTORE hStoreHandle = 0;         // Дескриптор хранилища сертификатов
static PCCERT_CONTEXT pCertSender = NULL;  // Контекст сертификата отправителя
static PCCERT_CONTEXT pCertResponder = NULL;    // Контекст сертификата получателя
static HCRYPTPROV hProvResponder = 0;       // Дескриптор CSP получателя
static HCRYPTPROV hProvSender = 0;         // Дескриптор CSP отправителя
static HCRYPTKEY hSenderKey = 0;            // Дескриптор открытого ключа отправителя
static HCRYPTKEY hResponderKey = 0;         // Дескриптор открытого ключа получателя
static HCRYPTKEY hSessionKey = 0;           // Дескриптор сессионного ключа
static HCRYPTKEY hAgreeKey = 0;     // Дескриптор ключа согласования

static BYTE *pbKeyBlobSimple = NULL;       // Указатель на сессионный ключевой BLOB
static BYTE *pbKeyBlobSender = NULL;       // Указатель на ключевой BLOB отправителя
static BYTE *pbKeyBlobResponder = NULL;    // Указатель на ключевой BLOB получателя

int main(void)
{
    DWORD dwBlobLenSimple;          // Длина сессионного ключевого BLOBа
    DWORD dwBlobLenSender;          // Длина ключевого BLOBа отправителя
    DWORD dwBlobLenResponder;       // Длина ключевого BLOBа получателя
    DWORD dwKeySpecSender;
    DWORD dwKeySpecResponder;

    // На стороне отправителя:

    // Открытие системного хранилища сертификатов.
    hStoreHandle = CertOpenSystemStore(0, "MY");

    if(hStoreHandle)
    {
        printf("The MY store is open. \n");
    }
    else
    {
        HandleError( "Error getting store handle.");
    }

    //--------------------------------------------------------------------
    // Получение контекста сертифика, в названии которого содержится "Sender",
    // находящегося в хранилище сертификатов "MY".

    pCertSender = CertFindCertificateInStore(
        hStoreHandle,
        X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
        0,
        CERT_FIND_SUBJECT_STR,
        _TEXT("Sender"),
        NULL);

    if(pCertSender)
    {
        printf("The \" Sender \" certificate is found. \n");
    }
    else
    {
        HandleError( "Error finding certificate.");
    }

    //--------------------------------------------------------------------
    // Получение дескриптора CSP, включая доступ к связанному с ним ключевому
    // контейнеру для контекста сертификата pCertSender.

    if(CryptAcquireCertificatePrivateKey(
        pCertSender,
        0,
        NULL,
        &hProvSender,
        &dwKeySpecSender,
        NULL))
    {
        printf("The CSP handle has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptAcquireCertificatePrivateKey.");
    }

    //--------------------------------------------------------------------
    // Поиск сертифика, в названии которого содержится "Responder",
    // находящегося в хранилище сертификатов "MY".

    pCertResponder = CertFindCertificateInStore(
        hStoreHandle,
        X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
        0,
        CERT_FIND_SUBJECT_STR,
        _TEXT("Responder"),
        NULL);

    if(pCertResponder)
    {
        printf("The \" Responder \" certificate is found. \n");
    }
    else
    {
        HandleError( "Error finding certificate.");
    }

    //--------------------------------------------------------------------
    // Получение дескриптора открытого ключа получателя.

    if(CryptImportPublicKeyInfoEx(
        hProvSender,
        X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
        &(pCertResponder->pCertInfo->SubjectPublicKeyInfo),
        0,
        0,
        NULL,
        &hResponderKey))
    {
        printf("The responder public key has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptImportPublicKeyInfoEx public key.");
    }

    //--------------------------------------------------------------------
    // Определение размера BLOBа открытого ключа и распределение памяти.

    if(CryptExportKey(
        hResponderKey,
        0,
        PUBLICKEYBLOB,
        0,
        NULL,
        &dwBlobLenResponder))
    {
        printf("Size of the BLOB for the responder public key determined. \n");
    }
    else
    {
        HandleError("Error computing BLOB length.");
    }

    pbKeyBlobResponder = (BYTE*)malloc(dwBlobLenResponder);

    if(pbKeyBlobResponder)
    {
        printf("Memory has been allocated for the BLOB. \n");
    }
    else
    {
        HandleError("Out of memory. \n");
    }
    //--------------------------------------------------------------------
    // Экспортирование открытого ключа получателя в BLOB открытого ключа.

    if(CryptExportKey(
        hResponderKey,
        0,
        PUBLICKEYBLOB,
        0,
        pbKeyBlobResponder,
        &dwBlobLenResponder))
    {
        printf("Contents have been written to the BLOB. \n");
    }
    else
    {
        HandleError("Error during CryptExportKey.");
    }

    //--------------------------------------------------------------------
    // Получение дескриптора закрытого ключа отправителя.

    if(CryptGetUserKey(
        hProvSender,
        dwKeySpecSender,
        &hSenderKey))
    {
        printf("The sender private key has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptGetUserKey private key.");
    }

    //--------------------------------------------------------------------
    // Получение ключа согласования импортом открытого ключа получателя из BLOBа
    // на закрытом ключе отправителя.

    if(CryptImportKey(
        hProvSender,
        pbKeyBlobResponder,
        dwBlobLenResponder,
        hSenderKey,
        0,
        &hAgreeKey))
    {
        printf("The responder public key has been imported. \n");
    }
    else
    {
        HandleError("Error during CryptImportKey public key.");
    }

    //--------------------------------------------------------------------
    // Генерация сессионного ключа.

    if(CryptGenKey(
        hProvSender,
        CALG_G28147,
        CRYPT_EXPORTABLE,
        &hSessionKey))
    {
        printf("Original session key is created. \n");
    }
    else
    {
        HandleError("ERROR -- CryptGenKey.");
    }

    //--------------------------------------------------------------------
    // pbKeyBlobSimple - зашифрованный сессионный ключ, передаем его получателю
    //
    //--------------------------------------------------------------------

    //--------------------------------------------------------------------
    // Определение размера BLOBа сессионного ключа и распределение памяти.

    if(CryptExportKey(
        hSessionKey,
        hAgreeKey,
        SIMPLEBLOB,
        0,
        NULL,
        &dwBlobLenSimple))
    {
        printf("Size of the BLOB for the sender session key determined. \n");
    }
    else
    {
        HandleError("Error computing BLOB length.");
    }

    pbKeyBlobSimple = (BYTE*)malloc(dwBlobLenSimple);

    if(pbKeyBlobSimple)
    {
        printf("Memory has been allocated for the BLOB. \n");
    }
    else
    {
        HandleError("Out of memory. \n");
    }
    //--------------------------------------------------------------------
    // Шифрование сессионного ключа на ключе Agree.

    if(CryptExportKey(
        hSessionKey,
        hAgreeKey,
        SIMPLEBLOB,
        0,
        pbKeyBlobSimple,
        &dwBlobLenSimple))
    {
        printf("Contents have been written to the BLOB. \n");
    }
    else
    {
        HandleError("Error during CryptExportKey.");
    }

    //--------------------------------------------------------------------
    // Закрытие системного хранилища сертификатов.

    if(CertCloseStore(
        hStoreHandle,
        0))
    {
        printf("The MY store is closed. \n");
        hStoreHandle=0;
    }
    else
    {
        HandleError( "Error closing store handle.");
    }

    CleanUp(FALSE);

    //--------------------------------------------------------------------
    // На стороне получателя: получили зашифрованный сессионный ключ
    // pbKeyBlobSimple.
    //--------------------------------------------------------------------

    //--------------------------------------------------------------------
    // Открытие системного хранилища сертификатов.

    hStoreHandle = CertOpenSystemStore(0, "MY");
    if(hStoreHandle)
    {
        printf("The MY store is open. \n");
    }
    else
    {
        HandleError( "Error getting store handle.");
    }

    //--------------------------------------------------------------------
    // Получение контекста сертифика, в названии которого содержится "Responder",
    // находящегося в хранилище сертификатов "MY".

    pCertResponder = CertFindCertificateInStore(
        hStoreHandle,
        X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
        0,
        CERT_FIND_SUBJECT_STR,
        _TEXT("Responder"),
        NULL);

    if(pCertResponder)
    {
        printf("The \" Responder \" certificate is found. \n");
    }
    else
    {
        HandleError( "Error finding certificate.");
    }

    //--------------------------------------------------------------------
    // Получение дескриптора CSP, включая доступ к связанному с ним ключевому
    // контейнеру для контекста сертификата pCertResponder.

    if(CryptAcquireCertificatePrivateKey(
        pCertResponder,
        0,
        NULL,
        &hProvResponder,
        &dwKeySpecResponder,
        NULL))
    {
        printf("The CSP handle has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptAcquireCertificatePrivateKey.");
    }

    //--------------------------------------------------------------------
    // Поиск сертифика, в названии которого содержится "Sender",
    // находящегося в хранилище сертификатов "MY".

    pCertSender = CertFindCertificateInStore(
        hStoreHandle,
        X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
        0,
        CERT_FIND_SUBJECT_STR,
        _TEXT("Sender"),
        NULL);

    if(pCertSender)
    {
        printf("The \" Sender \" certificate is found. \n");
    }
    else
    {
        HandleError( "Error finding certificate.");
    }
    //--------------------------------------------------------------------
    // Получение дескриптора открытого ключа отправителя.

    if(CryptImportPublicKeyInfoEx(
        hProvResponder,
        X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
        &(pCertSender->pCertInfo->SubjectPublicKeyInfo),
        0,
        0,
        NULL,
        &hSenderKey))
    {
        printf("The sender public key has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptImportPublicKeyInfoEx public key.");
    }

    //--------------------------------------------------------------------
    // Определение размера BLOBа открытого ключа и распределение памяти.

    if(CryptExportKey(
        hSenderKey,
        0,
        PUBLICKEYBLOB,
        0,
        NULL,
        &dwBlobLenSender))
    {
        printf("Size of the BLOB for the sender public key determined. \n");
    }
    else
    {
        HandleError("Error computing BLOB length.");
    }

    pbKeyBlobSender = (BYTE*)malloc(dwBlobLenSender);

    if(pbKeyBlobSender)
    {
        printf("Memory has been allocated for the BLOB. \n");
    }
    else
    {
        HandleError("Out of memory. \n");
    }
    //--------------------------------------------------------------------
    // Экспортирование открытого ключа отправителя в BLOB открытого ключа.

    if(CryptExportKey(
        hSenderKey,
        0,
        PUBLICKEYBLOB,
        0,
        pbKeyBlobSender,
        &dwBlobLenSender))
    {
        printf("Contents have been written to the BLOB. \n");
    }
    else
    {
        HandleError("Error during CryptExportKey.");
    }

    //--------------------------------------------------------------------
    // Получение дескриптора закрытого ключа получателя.

    if(CryptGetUserKey(
        hProvResponder,
        dwKeySpecResponder,
        &hResponderKey))
    {
        printf("The responder private key has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptGetUserKey private key.");
    }

    //--------------------------------------------------------------------
    // Получение ключа согласования импортом открытого ключа отправителя из BLOBа
    // на закрытом ключе получателя.

    if(CryptImportKey(
        hProvResponder,
        pbKeyBlobSender,
        dwBlobLenSender,
        hResponderKey,
        0,
        &hAgreeKey))
    {
        printf("The sender public key has been imported. \n");
    }
    else
    {
        HandleError("Error during CryptImportKey public key.");
    }

    // Получение сессионного ключа импортом зашифрованного сессионного ключа
    // на ключе Agree.

    if(CryptImportKey(
        hProvResponder,
        pbKeyBlobSimple,
        dwBlobLenSimple,
        hAgreeKey,
        0,
        &hSessionKey))
    {
        printf("The session key has been imported. \n");
    }
    else
    {
        HandleError("Error during CryptImportKey session key.");
    }

    CleanUp(TRUE);

    printf("The program ran to completion without error. \n");
    return 0;
}

void CleanUp(BOOL all)
{

    if(pbKeyBlobResponder)
    {
            free(pbKeyBlobResponder);
            pbKeyBlobResponder=NULL;
    }
    if(pbKeyBlobSimple && all)
    {
            free(pbKeyBlobSimple);
            pbKeyBlobSimple=NULL;
    }
    if(pbKeyBlobSender)
    {
            free(pbKeyBlobSender);
            pbKeyBlobSender=NULL;
    }

    if(hStoreHandle)
    {
            CertCloseStore(hStoreHandle, 0);
            hStoreHandle=0;
    }

    // Освобождение дескриптора провайдера.
    if(hProvSender)
    {
        CryptReleaseContext(hProvSender, 0);
        hProvSender=0;
    }

    // Уничтожение дескриптора закрытого ключа получателя.
    if(hResponderKey)
    {
        CryptDestroyKey(hResponderKey);
        hResponderKey=0;
    }

    // Уничтожение дескриптора открытого ключа отправителя.
    if(hSenderKey)
    {
        CryptDestroyKey(hSenderKey);
        hSenderKey=0;
    }

    // Уничтожение сессионного ключа.
    if(hSessionKey)
    {
        CryptDestroyKey(hSessionKey);
        hSessionKey=0;
    }

    // Уничтожение ключа согласования.
    if(hAgreeKey)
    {
        CryptDestroyKey(hAgreeKey);
        hAgreeKey=0;
    }

    // Освобождение дескриптора провайдера.
    if(hProvResponder)
    {
        CryptReleaseContext(hProvResponder, 0);
        hProvResponder=0;
    }

    // Освобождение контекста сертификата.
    if(pCertSender)
    {
        CertFreeCertificateContext(pCertSender);
        pCertSender=NULL;
    }

    if(pCertResponder)
    {
        CertFreeCertificateContext(pCertResponder);
        pCertResponder=NULL;
    }
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Пример на закодирование и раскодирование данных

Этот пример демонстрирует использование следующих функций
  • CryptMsgCalculateEncodedLength в MS CryptoAPI 2.0 World Wide Web link
  • CryptMsgOpenToEncode в MS CryptoAPI 2.0 World Wide Web link
  • CryptMsgUpdate в MS CryptoAPI 2.0 World Wide Web link
  • CryptMsgGetParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptMsgClose в MS CryptoAPI 2.0 World Wide Web link
  • CryptMsgOpenToDecode в MS CryptoAPI 2.0 World Wide Web link
  • CryptMsgUpdate в MS CryptoAPI 2.0 World Wide Web link
  • CryptMsgGetParam в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
// Пример кода для закодирования и раскодирования сообщения.
//--------------------------------------------------------------------

#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
static void HandleError(char *s);

// Для устранения конфликта с определением CMSG_DATA в системном заголовочном файле socket.h на
// Unix-системах, тип сообщения CMSG_DATA переименован в CMSG_CAPILITE_DATA. Если socket.h не
// используется, то можно определить CMSG_DATA как:
//
// #define CMSG_DATA CMSG_CAPILITE_DATA
//
#ifdef UNIX
#define CMSG_DATA CMSG_CAPILITE_DATA
#endif // UNIX

int main(void)
{
//-------------------------------------------------------------
// Объявление и инициализация переменных. Они получают указатель на
// содержимое сообщения. Эта программа создает содержимое сообщения
// и получает указатель на него. В большинстве случаев, содержимое
// сообщения уже где-то существует и указатель на сообщение устанавливается
// приложением.

HCRYPTMSG hMsg;
BYTE* pbContent;     // Байтовый указатель на сообщение
DWORD cbContent;     // Длина сообщения
DWORD cbEncodedBlob;
BYTE *pbEncodedBlob;

//--------------------------------------------------------------------
//  Следующие ниже переменные используются только в фазе раскодирования.

DWORD cbDecoded;
BYTE *pbDecoded;

//--------------------------------------------------------------------
//  Начало выполнения. Отображение исходного сообщения.

pbContent = (BYTE*) "Security is our only business";
cbContent = (DWORD)(strlen((char *)pbContent)+1);

printf("The original message => %s\n",pbContent);

//--------------------------------------------------------------------
// Открытие сообщения для закодирования.

hMsg = CryptMsgOpenToEncode(
          MY_ENCODING_TYPE,        // Тип закодированного сообщения
          0,                       // Флаги
          CMSG_DATA,               // Тип сообщения
          NULL,                    // Указатель на структуру
          NULL,                    // Внутренний контекст ID объекта
          NULL);                   // Потоковая информация (не используется)

if(hMsg)
{
    printf("The message to be encoded has been opened. \n");
}
else
{
     HandleError("OpenToEncode failed");
}
//--------------------------------------------------------------------
// Обновление сообщения с данными.

if(CryptMsgUpdate(
        hMsg,         // Дескриптор сообщения
        pbContent,    // Указатель на содержимое
        cbContent,    // Размер содержимого
        TRUE))        // Последний вызов
{
     printf("Content has been added to the encoded message. \n");
}
else
{
      HandleError("MsgUpdate failed");
}
//--------------------------------------------------------------------
// Получение размера BLOBа закодированного сообщения.

if(CryptMsgGetParam(
       hMsg,                    // Дескриптор сообщения
       CMSG_CONTENT_PARAM,      // Тип параметров
       0,                       // Индекс
       NULL,                    // Указатель на BLOB
       &cbEncodedBlob)) {       // Размер BLOBа
    if(cbEncodedBlob) {
        printf("The length of the data has been calculated. \n");
    } else {
        HandleError("Getting cbEncodedBlob length failed");
    }
} else {
    HandleError("Getting cbEncodedBlob length failed");
}
//--------------------------------------------------------------------
// Распределени памяти под закодированный BLOB.

pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob);

if(pbEncodedBlob)
{
   printf("Memory has been allocated for the signed message. \n");
}
else
{
   HandleError("Memory allocation failed");
}

//--------------------------------------------------------------------
// Получение результирующего сообщения.

if(CryptMsgGetParam(
               hMsg,                      // Дескриптор сообщения
               CMSG_CONTENT_PARAM,        // Тип параметров
               0,                         // Индекс
               pbEncodedBlob,             // Указатель на BLOB
               &cbEncodedBlob))           // Размер BLOBа
{
    printf("Message encoded successfully. \n");
}
else
{
      HandleError("MsgGetParam failed");
}
//--------------------------------------------------------------------
// pbEncodedBlob сейчас указывает на закодированное, подписанное содержимое.

//--------------------------------------------------------------------
// Закрытие сообщения.

if(hMsg)
    CryptMsgClose(hMsg);

//--------------------------------------------------------------------
// Нижеследующий код осуществляет раскодирование сообщения.
// Этот код может быть включен здесь или может быть использован в
// автономной программе, если сообщение, подлежащее раскодированию,
// и его длина заданы.
// BLOB закодированного сообщения и его длина могут быть прочитаны
// с дискового файла или могут быть получены из e-mail сообщения или
// из других входных данных.

//--------------------------------------------------------------------
// Открытие сообщения для раскодирования.

hMsg = CryptMsgOpenToDecode(
               MY_ENCODING_TYPE,      // тип закодированного сообщения.
               0,                     // Флаги.
               0,                     // Поиск данных сообщения.
               0,                     // Криптографический провайдер.
               NULL,                  // Информация издателя.
               NULL);                 // потоковая информация.

if(hMsg)
{
     printf("The message to decode is open. \n");
}
else
{
    HandleError("OpenToDecode failed");
}
//--------------------------------------------------------------------
// Обновление сообщения с закодированным BLOBом.
// И pbEncodedBlob, закодированные данные,
// и cbEncodedBlob, длина закодированных данных,
// должны быть доступны.

printf("\nThe length of the encoded message is %d.\n\n",cbEncodedBlob);

if(CryptMsgUpdate(
    hMsg,                 // Дескриптор сообщения
    pbEncodedBlob,        // Указатель на закодированный BLOB
    cbEncodedBlob,        // Размер закодированного BLOBа
    TRUE))                // Последний вызов
{
      printf("The encoded BLOB has been added to the message. \n");
}
else
{
    HandleError("Decode MsgUpdate failed");
}
//--------------------------------------------------------------------
// Получение размера содержимого.

if(CryptMsgGetParam(
                  hMsg,                  // Дескриптор сообщения
                  CMSG_CONTENT_PARAM,    // Тип параметров
                  0,                     // Индекс
                  NULL,                  // Адрес возвращаемой
                                         // информации
                  &cbDecoded))           // Размер возвращаемой
                                         // информации
{
    printf("The decoded message size is %d. \n", cbDecoded);
}
else
{
    HandleError("Decode CMSG_CONTENT_PARAM failed");
}
//--------------------------------------------------------------------
// Распределение памяти.

pbDecoded = (BYTE *) malloc(cbDecoded);

if(pbDecoded)
{
     printf("Memory has been allocated for the decoded message.\n");
}
else
{
    HandleError("Decoding memory allocation failed.");
}
//--------------------------------------------------------------------
// Получение указателя на содержимое.

if(CryptMsgGetParam(
                  hMsg,                  // Дескриптор сообщения
                  CMSG_CONTENT_PARAM,    // Тип параметров
                  0,                     // Индекс
                  pbDecoded,             // Адрес возвращаемой
                                         // информации
                  &cbDecoded))           // Размер возвращаемой
                                         // информации
{
     printf("The message is %s.\n",(LPSTR)pbDecoded);
}
else
{
     HandleError("Decode CMSG_CONTENT_PARAM #2 failed");
}
//--------------------------------------------------------------------
// Освобождение.

if(pbEncodedBlob)
    free(pbEncodedBlob);
if(pbDecoded)
    free(pbDecoded);
if(hMsg)
    CryptMsgClose(hMsg);

printf("This program ran to completion without error. \n");
return 0;
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Пример на копирование закрытого ключа

Этот пример демонстрирует использование следующих функций
  • CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetProvParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptSetProvParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptExportKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptImportKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetKeyParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptSetKeyParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptDestroyKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptReleaseContext в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
// В данном примере реализовано копирование закрытого ключа AT_KEYEXCHANGE.
// Копирование ключа AT_SIGNATURE производится аналогично. Необходимо также
// произвести копирование соответствующих этим ключам сертификатов.
// Для корректной работы этой программы копируемые ключи должны быть
// созданы как exportable. Копирование ключа производится из контейнера
// с именем "Source" (который, соответственно, должен быть создан) в
// создаваемый контейнер с именем "Destination" (который, если он имеется,
// до начала работы программы должен быть удален).
//--------------------------------------------------------------------

static void HandleError(char *s);
static void CleanUp(void);

static HCRYPTPROV hProvResponder = 0;     // Дескриптор CSP получателя
static HCRYPTPROV hProvSender = 0;         // Дескриптор CSP отправителя
static HCRYPTKEY hSenderKey = 0;           // Дескриптор копирумого ключа AT_EXCHANGE
static HCRYPTKEY hResponderKey = 0;       // Дескриптор полученного ключа AT_EXCHANGE
static HCRYPTKEY hSenderEphemKey = 0;     // Дескриптор эфемерного ключа для отправителя
static HCRYPTKEY hResponderEphemKey = 0;  // Дескриптор эфемерного ключа для получателя
static HCRYPTKEY hSenderAgreeKey = 0;      // Дескриптор ключа согласования отправителя
static HCRYPTKEY hResponderAgreeKey = 0;  // Дескриптор ключа согласования получателя
static BYTE *pbKeyBlob = NULL;             // Указатель на ключевой BLOB

int  main (void)
{
    //--------------------------------------------------------------------
    //  Объявление и инициализация переменных.

    DWORD dwProvType = PROV_GOST_2012_256;   // Тип провайдера по умолчанию
    DWORD data_len = 0;                     // Длина буфера
    BYTE *oid = NULL;                       // Буфер для хранения параметров
    DWORD dwBlobLen = 0;                    // Длина ключевого BLOBа
    DWORD cAlg = CALG_PRO12_EXPORT;

    //--------------------------------------------------------------------
    // Получение дескриптора контейнера, в который осуществляется копирование
    // ключа (получатель).

    if(CryptAcquireContext(
        &hProvResponder,
#ifdef _WIN32
        "Destination",
#else
        "\\\\.\\HDIMAGE\\Destination",
#endif
        NULL,
        dwProvType,
        CRYPT_NEWKEYSET))
    {
        printf("The responder key container has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptAcquireContext.");
    }

    //--------------------------------------------------------------------
    // Получение дескриптора контейнера, из которого осуществляется копирование
    // ключа (отправитель).

    if(CryptAcquireContext(
        &hProvSender,
        "Source",
        NULL,
        dwProvType,
        0))
    {
        printf("The sender key container has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptAcquireContext.");
    }

    //--------------------------------------------------------------------
    // Копирование параметров контейнера-отправителя в контейнер-получатель
    // для параметра PP_HASHOID.

    //--------------------------------------------------------------------
    // Определение размера буфера и распределение памяти.

    if(CryptGetProvParam(
        hProvSender,
        PP_HASHOID,
        NULL,
        &data_len,
        0))
    {
        printf("Size of the buffer determined. \n");
    }
    else
    {
        HandleError("Error computing buffer length.");
    }

    oid = (BYTE *)malloc( data_len );
    if( !oid )
        HandleError("Out of memory. \n");

    //--------------------------------------------------------------------
    // Копирование параметров контейнера-отправителя в буфер.

    if(CryptGetProvParam(
        hProvSender,
        PP_HASHOID,
        oid,
        &data_len,
        0))
    {
        printf("Parameters have been written to the buffer. \n");
    }
    else
    {
        HandleError("Error during CryptGetProvParam.");
    }

    //--------------------------------------------------------------------
    // Установка параметров, находящихся в буфере, получателем.

    if(CryptSetProvParam(
        hProvResponder,
        PP_HASHOID,
        oid,
        0 ))
    {
        printf("The parameters have been set. \n");
    }
    else
    {
        free( oid );
        HandleError("Error during CryptSetProvParam.");
    }

    //--------------------------------------------------------------------
    //  Освобождение памяти, используемой буфером.
    free( oid );

    // Обнуление длины буфера для повторного использования.
    data_len = 0;

    //--------------------------------------------------------------------
    // Копирование параметров контейнера-отправителя в контейнер-получатель
    // для параметра PP_CIPHEROID.

    //--------------------------------------------------------------------
    // Определение размера буфера и распределение памяти.

    if(CryptGetProvParam(
        hProvSender,
        PP_CIPHEROID,
        NULL,
        &data_len,
        0))
    {
        printf("Size of the buffer determined. \n");
    }
    else
    {
        HandleError("Error computing buffer length.");
    }

    oid = (BYTE *)malloc( data_len );
    if( !oid )
        HandleError("Out of memory. \n");

    //--------------------------------------------------------------------
    // Копирование параметров контейнера-отправителя в буфер.

    if(CryptGetProvParam(
        hProvSender,
        PP_CIPHEROID,
        oid,
        &data_len,
        0))
    {
        printf("Parameters have been written to the buffer. \n");
    }
    else
    {
        free( oid );
        HandleError("Error during CryptGetProvParam.");
    }

    //--------------------------------------------------------------------
    // Установка параметров, находящихся в буфере, получателем.

    if(CryptSetProvParam(
        hProvResponder,
        PP_CIPHEROID,
        oid,
        0 ))
    {
        printf("The parameters have been set. \n");
    }
    else
    {
        free( oid );
        HandleError("Error during CryptSetProvParam.");
    }
    free( oid );

    //--------------------------------------------------------------------
    // Получение дескриптора закрытого ключа, который будет скопирован.
    if(CryptGetUserKey(
        hProvSender,
        AT_KEYEXCHANGE,
        &hSenderKey ))
    {
        printf("The sender private key has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptGetUserKey private key.");
    }

    //--------------------------------------------------------------------
    // Генерация эфемерного ключа в контейнере-отправителе.

    if(CryptGenKey(
        hProvSender,
        CALG_DH_GR3410_12_256_EPHEM,
        CRYPT_EXPORTABLE,
        &hSenderEphemKey))
    {
        printf("Ephemeral sender key is created. \n");
    }
    else
    {
        HandleError("ERROR -- CryptGenKey.");
    }

    //--------------------------------------------------------------------
    // Генерация эфемерного ключа в контейнере-получателе.

    if(CryptGenKey(
        hProvResponder,
        CALG_DH_GR3410_12_256_EPHEM,
        CRYPT_EXPORTABLE | CRYPT_PREGEN,
        &hResponderEphemKey))
    {
        printf("Ephemeral responder key is created. \n");
    }
    else
    {
        HandleError("ERROR -- CryptGenKey.");
    }

    //--------------------------------------------------------------------
    // Согласование параметра KP_DHOID, вырабатываемого в алгоритме
    // Диффи-Хелмана.
    //--------------------------------------------------------------------

    //--------------------------------------------------------------------
    // Определение размера BLOBа и распределение памяти.

    if(CryptGetKeyParam(
        hSenderEphemKey,
        KP_DHOID,
        NULL,
        &dwBlobLen,
        0))
    {
        printf("Size of the BLOB determined. \n");
    }
    else
    {
        HandleError("Error computing BLOB length.");
    }

    pbKeyBlob = (BYTE*)malloc(dwBlobLen);
    if(!pbKeyBlob)
        HandleError("Out of memory. \n");

    //--------------------------------------------------------------------
    // Копирование параметров ключа в BLOB.

    if(CryptGetKeyParam(
        hSenderEphemKey,
        KP_DHOID,
        pbKeyBlob,
        &dwBlobLen,
        0))
    {
        printf("Parameters have been written to the BLOB. \n");
    }
    else
    {
        HandleError("Error during CryptGetProvParam.");
    }

    //--------------------------------------------------------------------
    // Копирование параметров в hResponderEphemKey.

    if(CryptSetKeyParam(
        hResponderEphemKey,
        KP_DHOID,
        pbKeyBlob,
        0))
    {
        printf("The parameters have been set. \n");
    }
    else
    {
        HandleError("Error during CryptSetProvParam.");
    }

    //--------------------------------------------------------------------
    //  Освобождение памяти, используемой BLOBом.
    free(pbKeyBlob);
    pbKeyBlob = NULL;
    dwBlobLen = 0;

    //--------------------------------------------------------------------
    // Генерация ключа

    if(CryptSetKeyParam(
        hResponderEphemKey,
        KP_X,
        NULL,
        0))
    {
        printf("X parameter is generated. \n");
    }
    else
    {
        HandleError("Error during CryptSetKeyParam.");
    }

    //--------------------------------------------------------------------
    // Получение ключа согласования в контейнере - получателе.
    //--------------------------------------------------------------------

    //--------------------------------------------------------------------
    // Определение размера BLOBа эфемерного ключа и распределение памяти.

    if(CryptExportKey(
        hSenderEphemKey,
        0,
        PUBLICKEYBLOB,
        0,
        NULL,
        &dwBlobLen ))
    {
        printf("Size of the BLOB for the sender ephemeral key determined. \n");
    }
    else
    {
        HandleError("Error computing BLOB length.");
    }

    pbKeyBlob = (BYTE*)malloc(dwBlobLen);
    if(!pbKeyBlob)
        HandleError("Out of memory. \n");

    // Экспортирование эфемерного ключа отправителя в BLOB.
    if(CryptExportKey(
        hSenderEphemKey,
        0,
        PUBLICKEYBLOB,
        0,
        pbKeyBlob,
        &dwBlobLen ))
    {
        printf("Contents have been written to the BLOB. \n");
    }
    else
    {
        HandleError("Error during CryptExportKey.");
    }

    //--------------------------------------------------------------------
    // Получение ключа согласования получателя импортом эфемерного ключа отправителя
    // на эфемерном ключе получателя.

    if(CryptImportKey(
        hProvResponder,
        pbKeyBlob,
        dwBlobLen,
        hResponderEphemKey,
        0,
        &hResponderAgreeKey))
    {
        printf("The sender ephemeral key has been imported. \n");
    }
    else
    {
        HandleError("Error during CryptImportKey ephemeral key.");
    }

    //--------------------------------------------------------------------
    //  Освобождение памяти, используемой BLOBом.
    free(pbKeyBlob);
    pbKeyBlob = NULL;
    dwBlobLen = 0;

    //--------------------------------------------------------------------
    // Получение ключа согласования в контейнере - отправителе.
    //--------------------------------------------------------------------

    //--------------------------------------------------------------------
    // Определение размера BLOBа эфемерного ключа и распределение памяти.

    if(CryptExportKey(
        hResponderEphemKey,
        0,
        PUBLICKEYBLOB,
        0,
        NULL,
        &dwBlobLen ))
    {
        printf("Size of the BLOB for the responder ephemeral key determined. \n");
    }
    else
    {
        HandleError("Error computing BLOB length.");
    }

    pbKeyBlob = (BYTE*)malloc(dwBlobLen);
    if(!pbKeyBlob)
        HandleError("Out of memory. \n");

    // Экспортирование эфемерного ключа получателя в BLOB.
    if(CryptExportKey(
        hResponderEphemKey,
        0,
        PUBLICKEYBLOB,
        0,
        pbKeyBlob,
        &dwBlobLen ))
    {
        printf("Contents have been written to the BLOB. \n");
    }
    else
    {
        HandleError("Error during CryptExportKey.");
    }

    //--------------------------------------------------------------------
    // Получение ключа согласования получателя импортом эфемерного ключа получателя
    // на эфемерном ключе отправителя.

    if(CryptImportKey(
        hProvSender,
        pbKeyBlob,
        dwBlobLen,
        hSenderEphemKey,
        0,
        &hSenderAgreeKey))
    {
        printf("The responder ephemeral key has been imported. \n");
    }
    else
    {
        HandleError("Error during CryptImportKey ephemeral key.");
    }

    //--------------------------------------------------------------------
    //  Освобождение памяти, используемой BLOBом.
    free(pbKeyBlob);
    pbKeyBlob = NULL;
    dwBlobLen = 0;

    //--------------------------------------------------------------------
    // Конвертирование ключа согласования в сессионный в контейнере - отправителе.

    if(CryptSetKeyParam(
        hSenderAgreeKey,
        KP_ALGID,
        (BYTE*)&cAlg,
        0 ))
    {
        printf("The sender agree key has been converted. \n");
    }
    else
    {
        HandleError("Error during CryptSetKeyParam agree key.");
    }

    //--------------------------------------------------------------------
    // Конвертирование ключа согласования в сессионный в контейнере - получателе.

    if(CryptSetKeyParam(
        hResponderAgreeKey,
        KP_ALGID,
        (BYTE*)&cAlg,
        0 ))
    {
        printf("The responder agree key has been converted. \n");
    }
    else
    {
        HandleError("Error during CryptSetKeyParam agree key.");
    }

    //--------------------------------------------------------------------
    // Экспорт копируемого пользовательского ключа  на сессионном.
    //--------------------------------------------------------------------

    //--------------------------------------------------------------------
    // Определение размера BLOBа ключа и распределение памяти.

    if(CryptExportKey(
        hSenderKey,
        hSenderAgreeKey,
        PRIVATEKEYBLOB,
        0,
        NULL,
        &dwBlobLen ))
    {
        printf("Size of the BLOB for the sender key determined. \n");
    }
    else
    {
        HandleError("Error computing BLOB length.");
    }

    pbKeyBlob = (BYTE*)malloc(dwBlobLen);
    if(!pbKeyBlob)
        HandleError("Out of memory. \n");

    // Экспорт копируемого пользовательского ключа  на сессионном.
    if(CryptExportKey(
        hSenderKey,
        hSenderAgreeKey,
        PRIVATEKEYBLOB,
        0,
        pbKeyBlob,
        &dwBlobLen ))
    {
        printf("Contents have been written to the BLOB. \n");
    }
    else
    {
        HandleError("Error during CryptExportKey.");
    }

    //--------------------------------------------------------------------
    // Получение копируемого ключа импортом пользовательского ключа на ключе
    // согласования.

    if(CryptImportKey(
        hProvResponder,
        pbKeyBlob,
        dwBlobLen,
        hResponderAgreeKey,
        0,
        &hResponderKey))
    {
        printf("The private key has been imported. \n");
    }
    else
    {
        HandleError("Error during CryptImportKey private key.");
    }

    //--------------------------------------------------------------------
    //  Освобождение памяти, используемой BLOBом.
    free(pbKeyBlob);
    pbKeyBlob = NULL;
    dwBlobLen = 0;

    //--------------------------------------------------------------------
    // Копирование параметров ключа hSenderKey в параметры ключа hResponderKey
    // для KP_CERTIFICATE.

    //--------------------------------------------------------------------
    // Определение размера BLOBа и распределение памяти.

    if(CryptGetKeyParam(
        hSenderKey,
        KP_CERTIFICATE,
        NULL,
        &dwBlobLen,
        0))
    {
        printf("Size of the BLOB determined. \n");
    }
    else
    {
        HandleError("Error computing BLOB length.");
    }

    pbKeyBlob = (BYTE*)malloc(dwBlobLen);

    if(pbKeyBlob)
    {
        printf("Memory has been allocated for the BLOB. \n");
    }
    else
    {
        HandleError("Out of memory. \n");
    }

    //--------------------------------------------------------------------
    // Копирование параметров ключа в BLOB.

    if(CryptGetKeyParam(
        hSenderKey,
        KP_CERTIFICATE,
        pbKeyBlob,
        &dwBlobLen,
        0))
    {
        printf("Parameters have been written to the BLOB. \n");
    }
    else
    {
        HandleError("Error during CryptGetProvParam.");
    }

    //--------------------------------------------------------------------
    // Копирование параметров в hResponderKey.

    if(CryptSetKeyParam(
        hResponderKey,
        KP_CERTIFICATE,
        pbKeyBlob,
        0))
    {
        printf("The parameters have been set. \n");
    }
    else
    {
        HandleError("Error during CryptSetProvParam.");
    }

    CleanUp();
    return 0;
}

void CleanUp(void)
{
    free(pbKeyBlob);

    // Освобождение дескриптора провайдера.
    if(hProvResponder)
        CryptReleaseContext(hProvResponder, 0);
    if(hProvSender)
        CryptReleaseContext(hProvSender, 0);

    // Уничтожение дескрипторов ключей.
    if(hSenderKey)
        CryptDestroyKey(hSenderKey);

    if(hResponderKey)
        CryptDestroyKey(hResponderKey);

    if(hSenderEphemKey)
        CryptDestroyKey(hSenderEphemKey);

    if(hResponderEphemKey)
        CryptDestroyKey(hResponderEphemKey);

    if(hSenderAgreeKey)
        CryptDestroyKey(hSenderAgreeKey);

    if(hResponderAgreeKey)
        CryptDestroyKey(hResponderAgreeKey);
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Пример на работу в режиме SILENT, без окон

Этот пример демонстрирует использование следующих функций
  • CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetProvParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetUserKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptDestroyKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptReleaseContext в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
// Пример кода для работы в режиме SILENT, без окон.
// В данном примере осуществляется подпись строки.
// Для корректной работы этой программы необходимо создать контейнер с
// именем "Source" и с паролем "1234". При этом в контейнере должны
// существовать оба ключа (ключ обмена и ключ подписи).
// Замечание: под win32 рекомендуется использовать _s аналоги CRT функций.
//--------------------------------------------------------------------

static void HandleError(char *s);
static void CleanUp(void);

static HCRYPTPROV hProv = 0;            // Дескриптор CSP
static HCRYPTKEY hKey = 0;              // Дескриптор ключа
static HCRYPTHASH hHash = 0;
static BYTE *pbHash = NULL;
static BYTE *pbKeyBlob = NULL;
static BYTE *pbSignature = NULL;
#ifdef _WIN32
#define CONTAINER "\\\\.\\Registry\\Source"
#else
#define CONTAINER "\\\\.\\HDIMAGE\\test"
#endif

int main(void)
{
    BYTE *pbBuffer = (BYTE *)"The data that is to be hashed and signed.";
    DWORD dwBufferLen = (DWORD)(strlen((char *)pbBuffer)+1);
    DWORD cbHash;
    DWORD dwSigLen;
    DWORD dwBlobLen;
    FILE *signature;

    // Получение дескриптора провайдера.
    if(CryptAcquireContext(
        &hProv,
        CONTAINER,
        NULL,
        PROV_GOST_2012_256,
        CRYPT_SILENT))
    {
        printf("CryptAcquireContext succeeded.\n");
    }
    else
    {
        if(GetLastError() == 0x80090016)
        {
            printf(" The key container with name \"Source\" does not exist.\n");
            printf(" Create a container and generate keys \n");
            exit(0);
        }
        else
        {
            HandleError("A general error occurred in CryptAcquireContext.");
        }
    }

    //--------------------------------------------------------------------
    // Установка параметров в соответствии с паролем.

    if(CryptSetProvParam(
        hProv,
        PP_KEYEXCHANGE_PIN,
        (BYTE*)"1234",
        0))
    {
        printf("CryptSetProvParam succeeded.\n");
    }
    else
    {
        HandleError("Error during CryptSetProvParam.");
    }

    //--------------------------------------------------------------------
    // Получение ключа пользователя.

    if(CryptGetUserKey(
        hProv,
        AT_SIGNATURE,
        &hKey))
    {
        printf("CryptGetUserKey succeeded.\n");
    }
    else
    {
        HandleError("Error during CryptGetUserKey.");
    }

    //--------------------------------------------------------------------
    // Экпорт открытого ключа. Здесь открытый ключ экспортируется в
    // PUBLICKEYBLOB для того, чтобы получатель подписанного хеша мог
    // проверить подпись. Этот BLOB может быть записан в файл и передан
    // другому пользователю.

    if(CryptExportKey(
        hKey,
        0,
        PUBLICKEYBLOB,
        0,
        NULL,
        &dwBlobLen))
    {
        printf("Size of the BLOB for the public key determined. \n");
    }
    else
    {
        if(GetLastError() == 0x8010006B) /* SCARD_W_WRONG_CHV */
        {
            printf(" The password of key container is differ from \"1234\".\n");
            exit(0);
        }
        else
        {
            HandleError("Error computing BLOB length.");
        }
    }

    // Распределение памяти под pbKeyBlob.
    pbKeyBlob = (BYTE*)malloc(dwBlobLen);
    if(!pbKeyBlob)
        HandleError("Out of memory. \n");

    // Сам экспорт в ключевой BLOB.
    if(CryptExportKey(
        hKey,
        0,
        PUBLICKEYBLOB,
        0,
        pbKeyBlob,
        &dwBlobLen))
    {
        printf("Contents have been written to the BLOB. \n");
    }
    else
    {
        HandleError("Error during CryptExportKey.");
    }
    //--------------------------------------------------------------------
    // Создание объекта функции хеширования.

    if(CryptCreateHash(
        hProv,
        CALG_GR3411_2012_256,
        0,
        0,
        &hHash))
    {
        printf("Hash object created. \n");
    }
    else
    {
        HandleError("Error during CryptCreateHash.");
    }

    //--------------------------------------------------------------------
    // Передача параметра HP_OID объекта функции хеширования.
    //--------------------------------------------------------------------

    //--------------------------------------------------------------------
    // Определение размера BLOBа и распределение памяти.

    if(CryptGetHashParam(hHash,
        HP_OID,
        NULL,
        &cbHash,
        0))
    {
        printf("Size of the BLOB determined. \n");
    }
    else
    {
        HandleError("Error computing BLOB length.");
    }

    pbHash = (BYTE*)malloc(cbHash);
    if(!pbHash)
        HandleError("Out of memory. \n");

    // Копирование параметра HP_OID в pbHash.

    if(CryptGetHashParam(hHash,
        HP_OID,
        pbHash,
        &cbHash,
        0))
    {
        printf("Parameters have been written to the pbHash. \n");
    }
    else
    {
        HandleError("Error during CryptGetHashParam.");
    }

    //--------------------------------------------------------------------
    // Вычисление криптографического хеша буфера.

    if(CryptHashData(
        hHash,
        pbBuffer,
        dwBufferLen,
        0))
    {
        printf("The data buffer has been hashed.\n");
    }
    else
    {
        HandleError("Error during CryptHashData.");
    }
    //--------------------------------------------------------------------
    // Определение размера подписи и распределение памяти.

    dwSigLen = 0;
    if(CryptSignHash(
        hHash,
        AT_SIGNATURE,
        NULL,
        0,
        NULL,
        &dwSigLen))
    {
        printf("Signature length %d found.\n",dwSigLen);
    }
    else
    {
        HandleError("Error during CryptSignHash.");
    }
    //--------------------------------------------------------------------
    // Распределение памяти под буфер подписи.

    pbSignature = (BYTE *)malloc(dwSigLen);
    if(!pbSignature)
        HandleError("Out of memory.");

    // Подпись объекта функции хеширования.
    if(CryptSignHash(
        hHash,
        AT_SIGNATURE,
        NULL,
        0,
        pbSignature,
        &dwSigLen))
    {
        printf("pbSignature is the hash signature.\n");
    }
    else
    {
        HandleError("Error during CryptSignHash.");
    }

    //if(!fopen_s(&signature, "signature.txt", "w+b" ))
    if(!(signature = fopen("signature.txt", "w+b")))
        HandleError( "Problem opening the file\n" );
    fwrite (pbSignature, 1, dwSigLen, signature);
    fclose(signature);

    CleanUp();

    printf("The program ran to completion without error. \n");
    return 0;
}

void CleanUp(void)
{
    if(pbHash)
        free(pbHash);
    if(pbKeyBlob)
        free(pbKeyBlob);
    if(pbSignature)
        free(pbSignature);

    // Уничтожение объекта функции хеширования.
    if(hHash)
        CryptDestroyHash(hHash);

    printf("The hash object has been destroyed.\n");
    printf("The signature is created.\n\n");

    // Уничтожение дескриптора ключа пользователя.

    if(hKey)
        CryptDestroyKey(hKey);

    // Освобождение дескриптора провайдера.

    if(hProv)
        CryptReleaseContext(hProv, 0);
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Пример экспорта закрытого ключа в блоб

Этот пример демонстрирует использование следующих функций
  • CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetUserKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptExportKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptImportKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptGenKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetKeyParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptDestroyKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptReleaseContext в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
// В данном примере реализовано шифрование закрытого ключа AT_KEYEXCHANGE
// на открытом ключе получателя.
//
// Следует сделить за тем, чтобы контейнеры "Sender" и "Responder",
// используемые в программах ExportInFile, EncryptKey и DecryptKey на момент
// выполнения этих программ существовали.
//--------------------------------------------------------------------

#pragma region Объявление переменных

#define BLOCK_LENGTH 4096
#define SALT_LENGTH 16

static void WriteBlobToFile(BYTE *pbData, DWORD cbData,char *FName);
static void HandleError(char *s);
static void CleanUp(void);

static HCRYPTPROV hProv = 0;            // Дескриптор CSP
static HCRYPTKEY hKey = 0;              // Дескриптор копируемого закрытого Ключа отправителя AT_EXCHANGE
static HCRYPTKEY hDerivedKey = 0;       // Дескриптор сессионного ключа
static HCRYPTHASH hHash = 0;            // Дескриптор хеша пароля

static BYTE *pbKeyBlobExport = NULL;    // Указатель на  BLOB копирумого закрытого Ключа отправителя AT_EXCHANGE
static BYTE *pbIV = NULL;               // Вектор инициализации закрытого Ключа

static CRYPT_DATA_BLOB salt = {0, NULL}; // Структура CRYPT_DATA_BLOB для хранения соли

#pragma endregion

#define MAX_PUBLICKEYBLOB_SIZE 200

int main(void)
{
    DWORD dwKeyBlobExportLen;           // Длина  BLOBа передаваемого ключа

    DWORD dwIV = 0;                     // Длина вектора инициализации
    ALG_ID ke_alg = CALG_PRO12_EXPORT;  // Алгоритм сессионного ключа

    char password[] = "password";   // Пароль
    CRYPT_DATA_BLOB password_blob;  // Структура CRYPT_DATA_BLOB для хранения пароля
    password_blob.cbData = (DWORD)strlen(password);
    password_blob.pbData = (BYTE*)password;

    // Получение дескриптора контейнера получателя с именем "Sender"
    if(CryptAcquireContext(
        &hProv,
        "Sender",
        NULL,
        PROV_GOST_2012_256,
        0))
    {
        printf("The key container \"Sender\" has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptAcquireContext.");
    }

    // Заполнение соли случайными байтами.
    salt.cbData = SALT_LENGTH;
    salt.pbData = (BYTE*)malloc(salt.cbData);
    if (!salt.pbData)
        HandleError("Out of memory.");
    CryptGenRandom(hProv, salt.cbData, salt.pbData);

    // Запись соли в файл.
    WriteBlobToFile(salt.pbData, salt.cbData, "salt.bin");

    //----------------------------------------------------------------------------
    // Хеширование пароля.
    //----------------------------------------------------------------------------

    // Создание пустого объекта хеширования.
    if (!CryptCreateHash(
        hProv,
        CALG_PBKDF2_2012_512,
        0,
        0,
        &hHash))
    {
        HandleError("CryptCreateHash failed.");
    }

    // Задание соли.
    if (!CryptSetHashParam(
        hHash,
        HP_PBKDF2_SALT,
        (BYTE*)&salt,
        0))
    {
        HandleError("CryptSetHashParam HP_PBKDF2_SALT failed.");
    }

    // Задание строки пароля.
    if (!CryptSetHashParam(
        hHash,
        HP_PBKDF2_PASSWORD,
        (BYTE*)&password_blob,
        0))
    {
        HandleError("CryptSetHashParam HP_PBKDF2_PASSWORD failed.");
    }

    //--------------------------------------------------------------------
    // Создание сессионного ключа, основанного на хеше, полученном из пароля.

    if(CryptDeriveKey(
        hProv,
        CALG_G28147,
        hHash,
        CRYPT_EXPORTABLE,
        &hDerivedKey))
    {
        printf("The key has been derived. \n");
    }
    else
    {
        HandleError("Error during CryptDeriveKey!");
    }

    // Установление PRO12_EXPORT алгоритма сессионного ключа
    if(CryptSetKeyParam(
        hDerivedKey,
        KP_ALGID,
        (LPBYTE)&ke_alg,
        0))
    {
        printf("PRO12_EXPORT agree key algorithm has been set. \n");
    }
    else
    {
        HandleError("Error during CryptSetKeyParam agree key.");
    }

    //--------------------------------------------------------------------
    // Зашифрование закрытого Ключа.
    //--------------------------------------------------------------------
    // Получение дескриптора закрытого Ключа, который будет скопирован.
    if(CryptGetUserKey(
        hProv,
        AT_KEYEXCHANGE,
        &hKey))
    {
        printf("The sender private key has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptGetUserKey private key.");
    }

    //--------------------------------------------------------------------
    // Определение размера вектора инициализации Ключа.
    if(CryptGetKeyParam(
        hDerivedKey,
        KP_SV,
        NULL,
        &dwIV,
        0))
    {
        printf("Size of the IV for the sender secret Key determined. \n");
    }
    else
    {
        HandleError("Error computing IV length.");

    }

    pbIV = (BYTE*)malloc(dwIV);
    if (!pbIV)
        HandleError("Out of memory. \n");

    // Определение вектора инициализации Ключа.
    if(CryptGetKeyParam(
        hDerivedKey,
        KP_IV,
        pbIV,
        &dwIV,
        0))
    {
        printf( "CryptGetKeyParam succeeded. \n");
    }
    else
    {
        HandleError("Error during CryptGetKeyParam.");
    }

    // Запись вектора инициализации в файл.
    WriteBlobToFile(pbIV, dwIV, "vector.bin");

    //--------------------------------------------------------------------
    // Определение размера BLOBа Ключа и распределение памяти.

    if(CryptExportKey(
        hKey,
        hDerivedKey,
        PRIVATEKEYBLOB,
        0,
        NULL,
        &dwKeyBlobExportLen))
    {
        printf("Size of the BLOB for the sender secret Key determined. \n");
    }
    else
    {
        HandleError("Error computing BLOB length.");
    }

    pbKeyBlobExport = (BYTE*)malloc(dwKeyBlobExportLen);

    if(!pbKeyBlobExport)
        HandleError("Out of memory. \n");

    // Зашифрование Ключа на ключе Derived.

    if(CryptExportKey(
        hKey,
        hDerivedKey,
        PRIVATEKEYBLOB,
        0,
        pbKeyBlobExport,
        &dwKeyBlobExportLen))
    {
        printf("Contents have been written to the BLOB. \n");
    }
    else
    {
        HandleError("Error during CryptExportKey.");
    }

    // запись блоба зашифрованного ключа
    WriteBlobToFile(pbKeyBlobExport, dwKeyBlobExportLen, "EncryptedKeyBlob.enc");
    return 0;
}

void WriteBlobToFile(BYTE *pbData, DWORD cbData, char *FName )
{
    FILE *file;

    // Открытие файла на запись в него BLOB-а
    if((file = fopen(FName, "wb")))
    {
        printf("The file '%s' was opened\n", FName);
    }
    else
    {
        fclose(file);
        HandleError("Problem opening the file\n");
    }

    // Запись BLOB-а в файл
    if(fwrite(pbData, 1, cbData, file))
    {
        printf("The blob was written to the '%s'\n", FName);
    }
    else
    {
        fclose(file);
        HandleError("The blob can not be written to file.");
    }

    fclose(file);
}

void CleanUp(void)
{
    // Уничтожение дескриптора копируемого закрытого ключа.
    if(hKey)
        CryptDestroyKey(hKey);

    // Уничтожение дескриптора сессионного ключа.
    if(hDerivedKey)
        CryptDestroyKey(hDerivedKey);

    // Уничтожение дескриптора хеша.
    if(hHash)
        CryptDestroyHash(hHash);

    // Освобождение дескриптора провайдера.
    if(hProv)
        CryptReleaseContext(hProv, 0);

    if(pbKeyBlobExport)
        free(pbKeyBlobExport);
    if(pbIV)
        free(pbIV);

    free(salt.pbData);
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Пример импорта закрытого ключа из блоба

Этот пример демонстрирует использование следующих функций
  • CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetUserKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptImportKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptSetKeyParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptDestroyKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptReleaseContext в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
// Данный пример демонстрирует импорт закрытого ключа из блоба.
// Блоб импортируемого закрытого Ключа хранится в файле EncryptedKeyBlob.enc.
// Для корректной работы этого примера передаваемые ему входные данные
// должны являться результатом работы примера EncryptKey.
// Для корректной расшифровки импортируемого блоба закрытого ключа
// необходимы вектор инициализации и соль, которые хранятся
// в файлах "vector.bin" и "salt.bin".
// Следует сделить за тем, чтобы контейнеры "Sender" и "Responder",
// используемые в программах ExportInFile, EncryptKey и DecryptKey на момент
// выполнения этих программ существовали.
// Замечание: под win32 рекомендуется использовать _s аналоги CRT функций.
//--------------------------------------------------------------------

#ifdef _WIN32
#   define CONTAINER_COPY "\\\\.\\registry\\SenderCopy"
#else
#   define CONTAINER_COPY "\\\\.\\hdimage\\SenderCopy"
#endif
#define CONTAINER_COPY_PIN "111"

#pragma region Объявление переменных

#define BLOCK_LENGTH 4096
#define SALT_LENGTH 16

static void HandleError(char *s);
static void CleanUp(void);

static HCRYPTPROV hProv = 0;            // Дескриптор CSP для получения переданного ключа
static HCRYPTKEY hKey = 0;              // Дескриптор переданного закрытого Ключа отправителя AT_EXCHANGE
static HCRYPTKEY hDerivedKey = 0;       // Дескриптор сессионного ключа в hProv
static HCRYPTHASH hHash = 0;            // Дескриптор хеша пароля

static FILE *vectorf=NULL;              // Файл для хранения вектора инициализации
static FILE *saltf = NULL;              // Файл для хранения соли
static FILE *EncryptedKeyBlob = NULL;   // Файл блоба зашифрованного закрытого Ключа

static CRYPT_DATA_BLOB salt = {0, NULL}; // Структура CRYPT_DATA_BLOB для хранения соли

//#define PROVIDER_NAME NULL
//#define PROVIDER_NAME "CP2001KC1"

#pragma endregion

int main(void)
{
    BYTE *pbKeyBlobExport = NULL;    // Указатель на  BLOB переданного закрытого Ключа

    DWORD dwKeyBlobExportLen;   // Длина блоба переданного закрытого Ключа

    BYTE pbIV[100];             // Вектор инициализации сессионного ключа
    DWORD dwIV = 0;             // Длина вектора инициализации

    DWORD szf;

    ALG_ID ke_alg = CALG_PRO12_EXPORT; // Алгоритм сессионного ключа

    char password[] = "password";   // Пароль
    CRYPT_DATA_BLOB password_blob;  // Структура CRYPT_DATA_BLOB для хранения пароля
    password_blob.pbData = (BYTE*)password;
    password_blob.cbData = (DWORD)strlen(password);

    // Выделение памяти под соль.
    salt.cbData = SALT_LENGTH;
    salt.pbData = (BYTE*)malloc(salt.cbData);
    if (!salt.pbData)
        HandleError("Out of memory.");

    // Открытие файла, в котором хранится соль.
    if(!(saltf = fopen("salt.bin", "r+b")))
        HandleError( "Problem opening file 'salt.bin'\n" );
    printf( "File 'salt.bin' was opened\n" );

    // Чтение соли из файла.
    salt.cbData = (DWORD)fread(salt.pbData, 1, salt.cbData, saltf);
    if(!salt.cbData)
        HandleError( "Failed to read salt from 'salt.bin'\n" );
    printf( "Salt was read from 'salt.bin'\n" );

    // Открытие файла, в котором хранится вектор инициализации.
    if(!(vectorf = fopen("vector.bin", "r+b")))
        HandleError( "Problem opening the file 'vector.bin'\n" );
    printf( "The file 'vector.bin' was opened\n" );

    // Чтение вектора инициализации из файла.
    dwIV = (DWORD)fread(pbIV, 1, 100, vectorf);
    if(!dwIV)
        HandleError( "The IV can not be reading from the 'vector.bin'\n" );
    printf( "The IV was read from the 'vector.bin'\n" );

    //Открытие Файла блоба зашифрованного закрытого Ключа
    if(!(EncryptedKeyBlob = fopen("EncryptedKeyBlob.enc", "r+b")))
        HandleError( "Problem opening the file 'EncryptedKeyBlob.enc'\n" );
    printf( "The file 'EncryptedKeyBlob.enc' was opened\n" );

    //------------------------------------------------------------------
    // получение зашифрованного закрытого Ключа
    //------------------------------------------------------------------
    // находим размер файла EncryptedKeyBlob.enc, записываем его в szfile
    fseek(EncryptedKeyBlob, 0, SEEK_END);
    szf = ftell(EncryptedKeyBlob);
    fseek(EncryptedKeyBlob, 0, SEEK_SET);

    // выделение памяти
    pbKeyBlobExport = (BYTE*)malloc(szf);
    if (!pbKeyBlobExport)
        HandleError("Out of memory.");

    // чтение зашифрованного закрытого Ключа из файла EncryptedKeyBlob.enc
    dwKeyBlobExportLen = (DWORD)fread(pbKeyBlobExport, 1, szf, EncryptedKeyBlob);
    if(!dwKeyBlobExportLen)
        HandleError( "The private Key can not be reading from the 'EncryptedKeyBlob.enc'\n" );
    printf( "The private Key was read from the 'EncryptedKeyBlob.enc'\n" );

    //------------------------------------------------------------------
    //------------------------------------------------------------------
    // Получение дескриптора контейнера с именем "ResponderCopy",
    // для хранения переданного закрытого Ключа.
    if(!CryptAcquireContext(
        &hProv,
        CONTAINER_COPY,
        NULL,
        PROV_GOST_2012_256,
        CRYPT_DELETEKEYSET | CRYPT_SILENT))
    {
        printf("ResponderCopy does not exist\n");
    }

    if(!CryptAcquireContext(
        &hProv,
        CONTAINER_COPY,
        NULL,
        PROV_GOST_2012_256,
        CRYPT_NEWKEYSET))
    {
        HandleError("Error during CryptAcquireContext");
    }

    if (!CryptSetProvParam(
        hProv,
        PP_KEYEXCHANGE_PIN,
        (BYTE*)CONTAINER_COPY_PIN,
        0))
    {
        HandleError("Failed to set PIN");
    }

    printf("The key container \"ResponderCopy\" has been acquired. \n");

    //-----------------------------------------------------------------
    // Хеширование пароля
    //-----------------------------------------------------------------

    // Создание пустого объекта хеширования.
    if (!CryptCreateHash(
        hProv,
        CALG_PBKDF2_2012_512,
        0,
        0,
        &hHash))
    {
        HandleError("CryptCreateHash failed.");
    }

    // Задание соли.
    if (!CryptSetHashParam(
        hHash,
        HP_PBKDF2_SALT,
        (BYTE*)&salt,
        0))
    {
        HandleError("CryptSetHashParam HP_PBKDF2_SALT failed.");
    }

    // Задание строки пароля.
    if (!CryptSetHashParam(
        hHash,
        HP_PBKDF2_PASSWORD,
        (BYTE*)&password_blob,
        0))
    {
        HandleError("CryptSetHashParam HP_PBKDF2_PASSWORD failed.");
    }

    //--------------------------------------------------------------------
    // Создание сессионного ключа, основанного на хеше, полученном из пароля.

    if(CryptDeriveKey(
        hProv,
        CALG_G28147,
        hHash,
        CRYPT_EXPORTABLE,
        &hDerivedKey))
    {
        printf("The key has been derived. \n");
    }
    else
    {
        HandleError("Error during CryptDeriveKey!");
    }

    // Установление PRO12_EXPORT алгоритма сессионного ключа
    if(CryptSetKeyParam(
        hDerivedKey,
        KP_ALGID,
        (LPBYTE)&ke_alg,
        0))
    {
        printf("PRO12_EXPORT agree key algorithm has been set. \n");
    }
    else
    {
        HandleError("Error during CryptSetKeyParam agree key.");
    }

    //-----------------------------------------------------------------
    // Расшифрование закрытого переданного Ключа
    //-----------------------------------------------------------------
    // Установка вектора инициализации - без него первые 8 байт
    // расшифруются неправильно.
    if(!CryptSetKeyParam(
        hDerivedKey,
        KP_SV,
        pbIV,
        0))
    {
        HandleError("Error during CryptSetKeyParam.");
    }
    printf( "CryptSetKeyParam succeeded. \n");

    // Получение закрытого Ключа импортом зашифрованного закрытого Ключа
    // на ключе Derived в контейнер
    if(CryptImportKey(
        hProv,
        pbKeyBlobExport,
        dwKeyBlobExportLen,
        hDerivedKey,
        0,
        &hKey))
    {
        printf("The private Key has been imported. \n");
    }
    else
    {
        HandleError("Error during CryptImportKey private Key.");
    }

    CleanUp();

    printf("The program ran to completion without error. \n");

    free(pbKeyBlobExport);

    return 0;

}// Конец main

void CleanUp(void)
{
    if (EncryptedKeyBlob)
        fclose (EncryptedKeyBlob);
    if(vectorf)
        fclose (vectorf);
    if(saltf)
        fclose(saltf);

    // Уничтожение дескриптора переданного закрытого ключа.
    if(hKey)
        CryptDestroyKey(hKey);

    // Уничтожение дескриптора сессионного ключа.
    if(hDerivedKey)
        CryptDestroyKey(hDerivedKey);

    // Уничтожение дескриптора хеша.
    if(hHash)
        CryptDestroyHash(hHash);

    // Освобождение дескриптора провайдера.
    if(hProv)
        CryptReleaseContext(hProv, 0);

    free(salt.pbData);
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Пример поиска контейнера, соответствующего сертификату

Этот пример демонстрирует использование следующих функций
  • CertOpenStore в MS CryptoAPI 2.0 World Wide Web link
  • CertEnumCertificatesInStore в MS CryptoAPI 2.0 World Wide Web link
  • CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link
  • CryptImportPublicKeyInfo в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetKeyParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetProvParam в MS CryptoAPI 2.0 World Wide Web link
  • CertCloseStore в MS CryptoAPI 2.0 World Wide Web link
  • CryptDestroyKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptReleaseContext в MS CryptoAPI 2.0 World Wide Web link

//-------------------------------------------------------------------------------------
// Данный пример демонстрирует поиск контейнера соответствующего сертификату.
// Для проверки работы примера необходимо создать контейнер и положить соответствующий
// ему сертификат в файл test_search.cer. Программа возвращает имя найденного контейнера.
//-------------------------------------------------------------------------------------

BOOL CmpCertAndContFP(LPCSTR szContainerName, LPBYTE pbFPCert, DWORD cbFPCert);

static void HandleError(char *s);

int main(int argc, char **argv) {

    //------------------------------------------------------------------------
    // Объявление переменных

    HCERTSTORE          hFileStore;         // Дескриптор хранилища сертификатов
    PCCERT_CONTEXT      pCertCtx;           // Контекст сертификата
    HCRYPTPROV          hCryptProv;         // Дескриптор криптопровайдера
    HCRYPTKEY           hPublicKey;         // Дескриптор ключа из сертификата
    LPBYTE              pbFPCert;           // Параметр FP из сертификата
    DWORD               cbFPCert;           // Размер параметра FP из сертификата
    LPBYTE              pbContainerName;    // Имя контейнера
    DWORD               cbContainerName;    // Размер имени контейнера
    DWORD               dwFlags;

    if (2 != argc)
    {
        HandleError("Wrong arguments!");
    }

    //------------------------------------------------------------------------
    // Создание хранилища сертификатов из файла

    if ((hFileStore = CertOpenStore(
        CERT_STORE_PROV_FILENAME_A,
        0,
        0,
        CERT_STORE_OPEN_EXISTING_FLAG,
        argv[1] // Файл с сертификатом
    )))
    {
        printf("The file store was created successfully.\n");
    }
    else
    {
        HandleError("An error occurred during creation of the file store!");
    }

    //------------------------------------------------------------------------
    // Получение контекста сертификата из хранилища

    if ((pCertCtx = CertEnumCertificatesInStore(hFileStore, NULL)))
    {
        printf("Certificate context was loaded from store.\n");
    }
    else
    {
        HandleError("Error during CertEnumCertificatesInStore!");
    }

    //------------------------------------------------------------------------
    // Получение дескриптора криптопровайдера

    if (CryptAcquireContext(
        &hCryptProv,
        NULL,
        NULL,
        PROV_GOST_2012_256,
        CRYPT_VERIFYCONTEXT))
    {
        printf("CryptAcquireContext succeeded. \n");
    }
    else
    {
        HandleError("Error during CryptAcquireContext!");
    }

    //------------------------------------------------------------------------
    // Получение дескриптора открытого ключа из сертификата

    if (CryptImportPublicKeyInfo(
        hCryptProv,
        pCertCtx->dwCertEncodingType,
        &pCertCtx->pCertInfo->SubjectPublicKeyInfo,
        &hPublicKey))
    {
        printf("CryptImportPublicKeyInfo succeeded. \n");
    }
    else
    {
        HandleError("Error during CryptImportPublicKeyInfo!");
    }

    //------------------------------------------------------------------------
    // Получение параметра KP_FP открытого ключа из сертификата

    // Получение размера параметра
    if (CryptGetKeyParam(hPublicKey, KP_FP, NULL, &cbFPCert, 0))
    {
        printf("CryptGetKeyParam KP_FP succeeded. \n");
    }
    else
    {
        HandleError("Error during CryptGetKeyParam!");
    }

    // Выделение памяти
    pbFPCert = (LPBYTE)malloc(cbFPCert);

    if (!pbFPCert)
    {
        HandleError("Fail to allocate memory!");
    }

    // Получение параметра
    if (CryptGetKeyParam(hPublicKey, KP_FP, pbFPCert, &cbFPCert, 0))
    {
        printf("CryptGetKeyParam KP_FP succeeded. \n");
    }
    else
    {
        HandleError("Error during CryptGetKeyParam!");
    }

    //------------------------------------------------------------------------
    // Получение имени первого контейнера

    // Получение размера параметра
    if (CryptGetProvParam(hCryptProv, PP_ENUMCONTAINERS, NULL, &cbContainerName, CRYPT_FIRST))
    {
        printf("CryptGetProvParam PP_ENUMCONTAINERS succeeded. \n");
    }
    else
    {
        HandleError("Error during CryptGetProvParam!");
    }

    // Выделение памяти
    pbContainerName = (LPBYTE)malloc(cbContainerName);

    if (!pbContainerName)
    {
        HandleError("Fail to allocate memory!");
    }

    //------------------------------------------------------------------------
    // Перебор всех контейнеров

    dwFlags = CRYPT_FIRST;
    while (CryptGetProvParam(hCryptProv, PP_ENUMCONTAINERS, pbContainerName, &cbContainerName, dwFlags | CRYPT_FQCN))
    {
        if (CmpCertAndContFP((LPCSTR)pbContainerName, pbFPCert, cbFPCert))
        {
            printf("Container found! Name: '%s'\n", pbContainerName);
            break;
        }
        dwFlags = CRYPT_NEXT;
    }

    //------------------------------------------------------------------------
    // Освобождение памяти

    if (pbContainerName)
        free(pbContainerName);

    if (pbFPCert)
        free(pbFPCert);

    if (hFileStore)
    {
        if (!CertCloseStore(hFileStore, CERT_CLOSE_STORE_FORCE_FLAG))
        {
            HandleError("Error during CertCloseStore!");
        }
    }

    if (hPublicKey)
    {
        if (!CryptDestroyKey(hPublicKey))
        {
            HandleError("Error during CryptDestroyKey!");
        }
    }

    if (hCryptProv)
    {
        if (!CryptReleaseContext(hCryptProv, 0))
        {
            HandleError("Error during CryptReleaseContext!");
        }
    }

    return 0;
}

BOOL CmpCertAndContFP(LPCSTR szContainerName, LPBYTE pbFPCert, DWORD cbFPCert) {

    HCRYPTPROV          hProvCont;
    LPBYTE              pbFPCont;
    DWORD               cbFPCont;
    BOOL                result = FALSE;

    //------------------------------------------------------------------------
    // Получение дескриптора контейнера

    if (CryptAcquireContext(
        &hProvCont,
        szContainerName,
        NULL,
        PROV_GOST_2012_256,
        CRYPT_VERIFYCONTEXT))
    {
        printf("CryptAcquireContext for '%s' succeeded. \n", szContainerName);
    }
    else
    {
        HandleError("Error during CryptAcquireContext!\n");
    }

    //------------------------------------------------------------------------
    // Получение параметра PP_SIGNATURE_KEY_FP для ключа в контейнере

    cbFPCont = cbFPCert; // Размер FP из контейнера равен размеру FP из сертификата
    pbFPCont = (LPBYTE)malloc(cbFPCont);

    if (CryptGetProvParam(hProvCont, PP_SIGNATURE_KEY_FP, pbFPCont, &cbFPCont, 0))
    {
        printf("CryptGetProvParam PP_SIGNATURE_KEY_FP for '%s' succeeded. \n", szContainerName);
        // Сравнение FP из сертификата с FP из контейнера
        if (!memcmp(pbFPCont, pbFPCert, cbFPCert)) {
            result = TRUE;
            goto Done;
        }
    }

    //------------------------------------------------------------------------
    // Получение параметра PP_EXCHANGE_KEY_FP для ключа в контейнере

    if (CryptGetProvParam(hProvCont, PP_EXCHANGE_KEY_FP, pbFPCont, &cbFPCont, 0))
    {
        printf("CryptGetProvParam PP_EXCHANGE_KEY_FP for '%s' succeeded. \n", szContainerName);
        // Сравнение FP из сертификата с FP из контейнера
        if (!memcmp(pbFPCont, pbFPCert, cbFPCert)) {
            result = TRUE;
            goto Done;
        }
    }

Done:

    if (pbFPCont)
        free(pbFPCont);

    if (hProvCont)
    {
        if (!CryptReleaseContext(hProvCont, 0))
        {
            HandleError("Error during CryptReleaseContext!");
        }
    }

    return result;
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Примеры использования функций хеширования

В данном разделе приводятся примеры, демонстрирующие использование функций хеширования криптопровайдера.

  • Пример на создание хеша
  • Пример на подпись объекта функции хеширования и проверку подписи
  • Пример на дублирование хеша
  • Пример использования объекта хэша PRFKEYMAT


Пример на создание хеша

Этот пример демонстрирует использование следующих функций
  • CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link
  • CryptCreateHash в MS CryptoAPI 2.0 World Wide Web link
  • CryptHashData в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetHashParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptDestroyHash в MS CryptoAPI 2.0 World Wide Web link
  • CryptReleaseContext в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
// Пример создания хеша из содержимого файла. Имя файла задается в
// командной строке и является обязательным параметром.
// Замечание: под win32 рекомендуется использовать _s аналоги CRT функций.
//--------------------------------------------------------------------

#define BUFSIZE 1024
#define GR3411LEN  64

int main(int argc, char *argv[])
{
    //-------------------------------------------------------------
    // Объявление и инициализация переменных.
    BOOL bIsReadingFailed = FALSE;
    HCRYPTPROV hProv = 0;
    HCRYPTHASH hHash = 0;
    FILE* hFile;
    BYTE rgbFile[BUFSIZE];
    DWORD cbRead = 0;
    BYTE rgbHash[GR3411LEN];
    DWORD cbHash = 0;
    CHAR rgbDigits[] = "0123456789abcdef";
    DWORD i;

    //--------------------------------------------------------------------
    // Проверка того, передано ли имя файла.
    if(argc != 2 || argv[1] == NULL)
    {
        HandleError("The file name is absent.\n");
    }

    //--------------------------------------------------------------------
    // Открытие файла.
    // if(!fopen_s(&hFile, argv[1], "r+b"))
    if(!(hFile = fopen(argv[1], "r+b" )))
    {
        HandleError("Error opening input file");
    }
    printf( "The file %s was opened\n", argv[1]);

    //--------------------------------------------------------------------
    // Получение дескриптора криптопровайдера.

    if(!CryptAcquireContext(
        &hProv,
        NULL,
        NULL,
        PROV_GOST_2012_256,
        CRYPT_VERIFYCONTEXT))
    {
        HandleError("CryptAcquireContext failed");
    }

    //--------------------------------------------------------------------
    // Создание пустого объекта функции хеширования.

    if(!CryptCreateHash(hProv, CALG_GR3411_2012_256, 0, 0, &hHash))
    {
        CryptReleaseContext(hProv, 0);
        HandleError("CryptCreateHash failed");
    }

    //--------------------------------------------------------------------
    // Чтение данных из файла и хеширование этих данных.

    do
    {
        cbRead = (DWORD)fread(rgbFile, 1, BUFSIZE, hFile);

        if(!cbRead)
        {
            bIsReadingFailed = TRUE;
            break;
        }

        if(!CryptHashData(hHash, rgbFile, cbRead, 0))
        {
            CryptReleaseContext(hProv, 0);
            CryptDestroyHash(hHash);
            HandleError("CryptHashData failed");
        }
    }
    while(!feof(hFile));

    if(bIsReadingFailed)
    {
        CryptReleaseContext(hProv, 0);
        CryptDestroyHash(hHash);
        HandleError("ReadFile failed");
    }

    //--------------------------------------------------------------------
    // Получение параметра объекта функции хеширования.
    cbHash = GR3411LEN;
    if(!CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0))
    {
        CryptDestroyHash(hHash);
        CryptReleaseContext(hProv, 0);
        HandleError("CryptGetHashParam failed");
    }

    printf("GR3411 hash of file %s is: ", argv[1]);
    for(i = 0; i < cbHash; i++)
    {
        printf("%c%c", rgbDigits[rgbHash[i] >> 4],
            rgbDigits[rgbHash[i] & 0xf]);
    }
    printf("\n");

    //--------------------------------------------------------------------
    // Освобождение.
    CryptDestroyHash(hHash);
    CryptReleaseContext(hProv, 0);
    fclose(hFile);

    return S_OK;
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Пример на подпись объекта функции хеширования и проверку подписи

Этот пример демонстрирует использование следующих функций
  • CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetUserKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptExportKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptCreateHash в MS CryptoAPI 2.0 World Wide Web link
  • CryptHashData в MS CryptoAPI 2.0 World Wide Web link
  • CryptSignHash в MS CryptoAPI 2.0 World Wide Web link
  • CryptDestroyHash в MS CryptoAPI 2.0 World Wide Web link
  • CryptImportKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptVerifySignature в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
// В этом примере реализованы создание подписи объекта функции хеширования
// и проверка этой электронно-цифровой подписи.
// Замечание: под win32 рекомендуется использовать _s аналоги CRT функций.
//--------------------------------------------------------------------

#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
#ifdef _WIN32
#define CONTAINER "test"
#else
#define CONTAINER "\\\\.\\HDIMAGE\\test"
#endif
static void HandleError(char *s);
static void CleanUp(void);

static HCRYPTPROV hProv = 0;
static HCRYPTHASH hHash = 0;
static HCRYPTKEY hKey = 0;
static HCRYPTKEY hPubKey = 0;
static BYTE *pbHash = NULL;
static BYTE *pbSignature = NULL;
static BYTE *pbKeyBlob = NULL;

int main(void)
{
    //-------------------------------------------------------------
    // Объявление и инициализация переменных.

    BYTE *pbBuffer= (BYTE *)"The data that is to be hashed and signed.";
    DWORD dwBufferLen = (DWORD)(strlen((char *)pbBuffer)+1);
    DWORD dwSigLen;
    DWORD dwBlobLen;
    DWORD cbHash;
    FILE *signature;

    // Получение дескриптора контекста криптографического провайдера.
    if(CryptAcquireContext(
        &hProv,
        CONTAINER,
        NULL,
        PROV_GOST_2012_256,
        0))
    {
        printf("CSP context acquired.\n");
    }
    else
    {
        HandleError("Error during CryptAcquireContext.");
    }
    //--------------------------------------------------------------------
    // Получение открытого ключа подписи. Этот открытый ключ будет
    // использоваться получателем хеша для проверки подписи.
    // В случае, когда получатель имеет доступ к открытому ключю
    // отправителя с помощью сертификата, этот шаг не нужен.

    if(CryptGetUserKey(
        hProv,
        AT_SIGNATURE,
        &hKey))
    {
        printf("The signature key has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptGetUserKey for signkey.");
    }
    //--------------------------------------------------------------------
    // Экпорт открытого ключа. Здесь открытый ключ экспортируется в
    // PUBLICKEYBOLB для того, чтобы получатель подписанного хеша мог
    // проверить подпись. Этот BLOB может быть записан в файл и передан
    // другому пользователю.

    if(CryptExportKey(
        hKey,
        0,
        PUBLICKEYBLOB,
        0,
        NULL,
        &dwBlobLen))
    {
        printf("Size of the BLOB for the public key determined. \n");
    }
    else
    {
        HandleError("Error computing BLOB length.");
    }
    //--------------------------------------------------------------------
    // Распределение памяти под pbKeyBlob.

    pbKeyBlob = (BYTE*)malloc(dwBlobLen);
    if(!pbKeyBlob)
        HandleError("Out of memory. \n");

    // Сам экспорт в ключевой BLOB.
    if(CryptExportKey(
        hKey,
        0,
        PUBLICKEYBLOB,
        0,
        pbKeyBlob,
        &dwBlobLen))
    {
        printf("Contents have been written to the BLOB. \n");
    }
    else
    {
        HandleError("Error during CryptExportKey.");
    }
    //--------------------------------------------------------------------
    // Создание объекта функции хеширования.

    if(CryptCreateHash(
        hProv,
        CALG_GR3411_2012_256,
        0,
        0,
        &hHash))
    {
        printf("Hash object created. \n");
    }
    else
    {
        HandleError("Error during CryptCreateHash.");
    }

    //--------------------------------------------------------------------
    // Передача параметра HP_OID объекта функции хеширования.
    //--------------------------------------------------------------------

    //--------------------------------------------------------------------
    // Определение размера BLOBа и распределение памяти.

    if(CryptGetHashParam(hHash,
        HP_OID,
        NULL,
        &cbHash,
        0))
    {
        printf("Size of the BLOB determined. \n");
    }
    else
    {
        HandleError("Error computing BLOB length.");
    }

    pbHash = (BYTE*)malloc(cbHash);
    if(!pbHash)
        HandleError("Out of memory. \n");

    // Копирование параметра HP_OID в pbHash.
    if(CryptGetHashParam(hHash,
        HP_OID,
        pbHash,
        &cbHash,
        0))
    {
        printf("Parameters have been written to the pbHash. \n");
    }
    else
    {
        HandleError("Error during CryptGetHashParam.");
    }

    //--------------------------------------------------------------------
    // Вычисление криптографического хеша буфера.

    if(CryptHashData(
        hHash,
        pbBuffer,
        dwBufferLen,
        0))
    {
        printf("The data buffer has been hashed.\n");
    }
    else
    {
        HandleError("Error during CryptHashData.");
    }

    // Определение размера подписи и распределение памяти.
    dwSigLen = 0;
    if(CryptSignHash(
        hHash,
        AT_SIGNATURE,
        NULL,
        0,
        NULL,
        &dwSigLen))
    {
        printf("Signature length %d found.\n",dwSigLen);
    }
    else
    {
        HandleError("Error during CryptSignHash.");
    }
    //--------------------------------------------------------------------
    // Распределение памяти под буфер подписи.

    pbSignature = (BYTE *)malloc(dwSigLen);
    if(!pbSignature)
        HandleError("Out of memory.");

    // Подпись объекта функции хеширования.
    if(CryptSignHash(
        hHash,
        AT_SIGNATURE,
        NULL,
        0,
        pbSignature,
        &dwSigLen))
    {
        printf("pbSignature is the hash signature.\n");
    }
    else
    {
        HandleError("Error during CryptSignHash.");
    }

    //if(!fopen_s(&signature, "signature.txt", "w+b" ))
    if(!(signature = fopen("signature.txt", "w+b")))
        HandleError( "Problem opening the file signature.txt\n" );

    fwrite(pbSignature, 1, dwSigLen, signature);

    // Уничтожение объекта функции хеширования.
    if(hHash)
        CryptDestroyHash(hHash);

    printf("The hash object has been destroyed.\n");
    printf("The signing phase of this program is completed.\n\n");

    //--------------------------------------------------------------------
    // Во второй части программы проверяется подпись.
    // Чаще всего проверка осуществляется в случае, когда различные
    // пользователи используют одну и ту же программу. Хеш, подпись,
    // а также PUBLICKEYBLOB могут быть прочитаны из файла, e-mail сообщения
    // или из другого источника.

    // Здесь используюся определенные ранее pbBuffer, pbSignature,
    // szDescription, pbKeyBlob и их длины.

    // Содержимое буфера pbBuffer представляет из себя некоторые
    // подписанные ранее данные.

    // Указатель szDescription на текст, описывающий данные, подписывается.
    // Это тот же самый текст описания, который был ранее передан
    // функции CryptSignHash.

    //--------------------------------------------------------------------
    // Получение откытого ключа пользователя, который создал цифровую подпись,
    // и импортирование его в CSP с помощью функции CryptImportKey. Она
    // возвращает дескриптор открытого ключа в hPubKey.

    if(CryptImportKey(
        hProv,
        pbKeyBlob,
        dwBlobLen,
        0,
        0,
        &hPubKey))
    {
        printf("The key has been imported.\n");
    }
    else
    {
        HandleError("Public key import failed.");
    }
    //--------------------------------------------------------------------
    // Создание нового объекта функции хеширования.

    if(CryptCreateHash(
        hProv,
        CALG_GR3411_2012_256,
        0,
        0,
        &hHash))
    {
        printf("The hash object has been recreated. \n");
    }
    else
    {
        HandleError("Error during CryptCreateHash.");
    }

    //--------------------------------------------------------------------
    // Вычисление криптографического хеша буфера.

    if(CryptHashData(
        hHash,
        pbBuffer,
        dwBufferLen,
        0))
    {
        printf("The new has been created.\n");
    }
    else
    {
        HandleError("Error during CryptHashData.");
    }
    //--------------------------------------------------------------------
    // Проверка цифровой подписи.

    if(CryptVerifySignature(
        hHash,
        pbSignature,
        dwSigLen,
        hPubKey,
        NULL,
        0))
    {
        printf("The signature has been verified.\n");
    }
    else
    {
        printf("Signature not validated!\n");
    }

    CleanUp();
    return 0;
}

void CleanUp(void)
{
    if(pbSignature)
        free(pbSignature);
    if(pbHash)
        free(pbHash);
    if(pbKeyBlob)
        free(pbKeyBlob);

    // Уничтожение объекта функции хеширования.
    if(hHash)
        CryptDestroyHash(hHash);

    if(hKey)
        CryptDestroyKey(hKey);

    if(hPubKey)
        CryptDestroyKey(hPubKey);

    // Освобождение дескриптора провайдера.
    if(hProv)
        CryptReleaseContext(hProv, 0);
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Пример на дублирование хеша

Этот пример демонстрирует использование следующих функций
  • CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link
  • CryptCreateHash в MS CryptoAPI 2.0 World Wide Web link
  • CryptHashData в MS CryptoAPI 2.0 World Wide Web link
  • CryptDuplicateHash в MS CryptoAPI 2.0 World Wide Web link
  • CryptSetHashParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetHashParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptDestroyHash в MS CryptoAPI 2.0 World Wide Web link
  • CryptReleaseContext в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
// В данном примере осуществляется хеширование строки, дублирование
// полученного хеша. Затем осуществляется хеширование дополнительных
// данных при помощи оригинального и дублированного хеша.
//--------------------------------------------------------------------

static void HandleError(char *s);
static void CleanUp(void);
static void Get_And_Print_Hash(HCRYPTHASH hHash);

static HCRYPTPROV   hCryptProv = 0;
static HCRYPTHASH   hOriginalHash = 0;
static HCRYPTHASH   hDuplicateHash = 0;

int main(void)
{
    // Получение дескриптора контекста криптографического провайдера.
    if(CryptAcquireContext(
        &hCryptProv,
        NULL,
        NULL,
        PROV_GOST_2012_256,
        CRYPT_VERIFYCONTEXT))
    {
        printf("CryptAcquireContext succeeded. \n");
    }
    else
    {
        HandleError("Error during CryptAcquireContext!");
    }
    //--------------------------------------------------------------------
    // Создание объекта функции хеширования.

    if(CryptCreateHash(
        hCryptProv,
        CALG_GR3411_2012_256,
        0,
        0,
        &hOriginalHash))
    {
        printf("An empty hash object has been created. \n");
    }
    else
    {
        HandleError("Error during CryptCreateHash.");
    }
    //--------------------------------------------------------------------
    // Хеширование байтовой строки.

    if(CryptHashData(
        hOriginalHash,
        (BYTE*)"Some Common Data",
        sizeof("Some Common Data"), 0))
    {
        printf("An original hash has been created. \n");
    }
    else
    {
        HandleError("Error during CryptHashData.");
    }
    //--------------------------------------------------------------------
    // Дублирование хеша.
    // Эта функция работает только в Windows 2000 и старше.

    if(CryptDuplicateHash(
        hOriginalHash,
        NULL,
        0,
        &hDuplicateHash))
    {
        printf("The hash has been duplicated. \n");
    }
    else
    {
        HandleError("Error during CryptDuplicateHash.");
    }

    printf("The original hash -- phase 1.\n");
    Get_And_Print_Hash(hOriginalHash);

    printf("The duplicate hash -- phase 1.\n");
    Get_And_Print_Hash(hDuplicateHash);

    //--------------------------------------------------------------------
    // Хеширование "Some Data" с оригинальным хешем.

    if(CryptHashData(
        hOriginalHash,
        (BYTE*)"Some Data",
        sizeof("Some Data"),
        0))
    {
        printf("Additional data has been hashed with the original. \n");
    }
    else
    {
        HandleError("Error during CryptHashData.");
    }
    //--------------------------------------------------------------------
    // Хеширование "Other Data" с дублированным хешем.

    if(CryptHashData(
        hDuplicateHash,
        (BYTE*)"Other Data",
        sizeof("Other Data"),
        0))
    {
        printf("More data has been hashed with the duplicate. \n");
    }
    else
    {
        HandleError("Error during CryptHashData.");
    }

    printf("The original hash -- phase 2.\n");
    Get_And_Print_Hash(hOriginalHash);

    printf("The duplicate hash -- phase 2.\n");
    Get_And_Print_Hash(hDuplicateHash);

    CleanUp();

    printf("The program ran to completion without error. \n");
    return 0;
}

// Определение функции Get_And_Print_Hash.
void Get_And_Print_Hash(HCRYPTHASH hOHash)
{
    BYTE         *pbHash;
    BYTE         *pbHashSize;
    DWORD        dwHashLen = sizeof(DWORD);
    DWORD        i;
    HCRYPTHASH   hHash=0;

    //--------------------------------------------------------------------
    // Дублирование установленного хеша.
    // Эта функция работает только в Windows 2000 и старше.
    // Хеш продублирован для того, чтобы не изменять исходный хеш.

    if(!CryptDuplicateHash(
        hOHash,
        NULL,
        0,
        &hHash))
    {
        HandleError("Error during CryptDuplicateHash.");
    }

    pbHashSize =(BYTE *) malloc(dwHashLen);
    if(!pbHashSize)
        HandleError("Memory allocation failed.");

    if(CryptGetHashParam(
        hHash,
        HP_HASHSIZE,
        pbHashSize,
        &dwHashLen,
        0))
    {
        // Работает. Освобождение pbHashSize.
        free(pbHashSize);
    }
    else
    {
        free(pbHashSize);
        HandleError("CryptGetHashParam failed to get size.");
    }

    if(!CryptGetHashParam(
        hHash,
        HP_HASHVAL,
        NULL,
        &dwHashLen,
        0))
    {
        HandleError("CryptGetHashParam failed to get length.");
    }

    pbHash = (BYTE*)malloc(dwHashLen);
    if(!pbHash)
        HandleError("Allocation failed.");

    if(CryptGetHashParam(
        hHash,
        HP_HASHVAL,
        pbHash,
        &dwHashLen,
        0))
    {
        // Печать значения хеша.
        printf("The hash is:  ");
        for(i = 0 ; i < dwHashLen ; i++)
        {
            printf("%2.2x ",pbHash[i]);
        }
        printf("\n");
        free(pbHash);
    }
    else
    {
        free(pbHash);
        HandleError("Error during reading hash value.");
    }

    if(!CryptDestroyHash(hHash))
    {
        HandleError("ERROR - CryptDestroyHash");
    }
}

void CleanUp(void)
{
    // Уничтожение оригинального хеша.
    if (hOriginalHash)
        CryptDestroyHash(hOriginalHash);
    printf("The original hash has been destroyed. \n");

    // Уничтожение дублированного хеша.
    if (hDuplicateHash)
        CryptDestroyHash(hDuplicateHash);
    printf("The duplicate hash has been destroyed. \n");

    // Освобождение CSP.
    if(hCryptProv)
        CryptReleaseContext(hCryptProv,0);
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Пример использования объекта хэша PRFKEYMAT

Этот пример демонстрирует использование следующих функций
  • CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link
  • CryptCreateHash в MS CryptoAPI 2.0 World Wide Web link
  • CryptSetHashParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetHashParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptDeriveKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptDestroyHash в MS CryptoAPI 2.0 World Wide Web link
  • CryptDestroyKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptReleaseContext в MS CryptoAPI 2.0 World Wide Web link

//-------------------------------------------------------------------------------------------------------------
// Данный пример демонстрирует использование объекта хэша PRFKEYMAT (CALG_GR3411_PRFKEYMAT,
// CALG_GR3411_2012_256_PRFKEYMAT и CALG_GR3411_2012_512_PRFKEYMAT) для получения последовательности
// псевдослучайных данных произвольной длины, а также для получения ключей CALG_G28147 и CALG_SYMMETRIC_512.
//-------------------------------------------------------------------------------------------------------------

static void HandleError(char *s);

int main() {

    //------------------------------------------------------------------------
    // Объявление переменных.

    HCRYPTPROV hProv = 0;
    HCRYPTKEY hPrfKey = 0;
    HCRYPTHASH hPrfHash = 0;

    CRYPT_DATA_BLOB prfSeedBlob;
    BYTE pbPrfSeedData[] = { 0x11, 0x22, 0x33, 0x44 };

    BYTE pbDataFirst[10];
    DWORD cbDataFirst = 0;

    HCRYPTKEY hDerivedKey256 = 0;

    BYTE pbDataSecond[100];
    DWORD cbDataSecond = 0;

    HCRYPTKEY hDerivedKey512 = 0;

    //------------------------------------------------------------------------
    // Получение дескриптора контекста криптографического провайдера.

    if(CryptAcquireContext(
        &hProv,
        NULL,
        NULL,
        PROV_GOST_2012_256,
        CRYPT_VERIFYCONTEXT))
    {
        printf("CSP context acquired.\n");
    }
    else
    {
        HandleError("Error during CryptAcquireContext.");
    }

    //------------------------------------------------------------------------
    // Генерация ключа для PRF.

    if(CryptGenKey(
        hProv,
        CALG_G28147,
        0,
        &hPrfKey))
    {
        printf("PRF key is created. \n");
    }
    else
    {
        HandleError("Error during CryptGenKey.");
    }

    //------------------------------------------------------------------------
    // Создание объекта хэша PRF.

    if(CryptCreateHash(
        hProv,
        CALG_GR3411_2012_256_PRFKEYMAT,
        hPrfKey,
        0,
        &hPrfHash))
    {
        printf("PRF hash is created. \n");
    }
    else
    {
        HandleError("Error during CryptCreateHash.");
    }

    //------------------------------------------------------------------------
    // Устанавливаем seed для PRF.

    prfSeedBlob.pbData = pbPrfSeedData;
    prfSeedBlob.cbData = sizeof(pbPrfSeedData);

    if(CryptSetHashParam(
        hPrfHash,
        HP_PRFKEYMAT_SEED,
        (LPBYTE)&prfSeedBlob,
        0))
    {
        printf("PRF seed is set. \n");
    }
    else
    {
        HandleError("Error during CryptSetHashParam.");
    }

    //------------------------------------------------------------------------
    // Получаем последовательность данных необходимой длины.

    cbDataFirst = sizeof(pbDataFirst);

    if(CryptGetHashParam(
        hPrfHash,
        HP_HASHVAL,
        pbDataFirst,
        &cbDataFirst,
        0))
    {
        printf("First part of data produced. \n");
    }
    else
    {
        HandleError("Error during CryptGetHashParam.");
    }

    //------------------------------------------------------------------------
    // Получаем ключ 256 бит.

    if(CryptDeriveKey(
        hProv,
        CALG_G28147,
        hPrfHash,
        0,
        &hDerivedKey256))
    {
        printf("256-bit key derived. \n");
    }
    else
    {
        HandleError("Error during CryptDeriveKey.");
    }

    //------------------------------------------------------------------------
    // Получаем еще последовательность данных необходимой длины.

    cbDataSecond = sizeof(pbDataSecond);

    if(CryptGetHashParam(
        hPrfHash,
        HP_HASHVAL,
        pbDataSecond,
        &cbDataSecond,
        0))
    {
        printf("Second part of data produced. \n");
    }
    else
    {
        HandleError("Error during CryptGetHashParam.");
    }

    //------------------------------------------------------------------------
    // Получаем ключ 512 бит.

    if(CryptDeriveKey(
        hProv,
        CALG_SYMMETRIC_512,
        hPrfHash,
        0,
        &hDerivedKey512))
    {
        printf("512-bit key derived. \n");
    }
    else
    {
        HandleError("Error during CryptDeriveKey.");
    }

    //------------------------------------------------------------------------
    // Освобождение памяти.

    if (hDerivedKey256) {
        CryptDestroyKey(hDerivedKey256);
    }

    if (hDerivedKey512) {
        CryptDestroyKey(hDerivedKey512);
    }

    if (hPrfHash) {
        CryptDestroyHash(hPrfHash);
    }

    if (hPrfKey) {
        CryptDestroyKey(hPrfKey);
    }

    if (hProv) {
        CryptReleaseContext(hProv, 0);
    }

    return 0;
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Примеры использования функций шифрования

В данном разделе приводятся примеры, демонстрирующие использование функций шифрования криптопровайдера.

Для корректной работы примеров, касающихся зашифрования и расшифрования файла, необходимо соблюдать следующую последовательность их использования:

1) Запись открытого ключа в файл.

2) Зашифрование файла.

3) Расшифрование файла.

  • Пример на CryptEncryptMessage и CryptDecryptMessage
  • Пример на запись открытого ключа в файл
  • Пример на зашифрование файла
  • Пример на расшифрование файла


Пример на CryptEncryptMessage и CryptDecryptMessage

Этот пример демонстрирует использование следующих функций
  • CryptEncryptMessage в MS CryptoAPI 2.0 World Wide Web link
  • CryptDecryptMessage в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
// Пример кода для зашифрования данных и создания зашифрованного
// сообщения при помощи функции CryptEncryptMessage.

// Для функционирования данного кода необходимы:
// - контейнер с ключом AT_KEYEXCHANGE в провайдере PROV_GOST_2012_256
// - сертификат этого ключа, установленный в хранилище пользователя ("MY")
//--------------------------------------------------------------------

#define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)

static void CleanUp(void);
static void HandleError(const char *s);
static PCCERT_CONTEXT GetRecipientCert(HCERTSTORE hCertStore);
static void DecryptMessage(BYTE *pbEncryptedBlob, DWORD cbEncryptedBlob);
static void GetCertDName(PCERT_NAME_BLOB pNameBlob, char **pszName);

static HCRYPTPROV hCryptProv = 0;        // дескриптор CSP
static HCERTSTORE hStoreHandle = 0;      // дескриптор хранилища сертификатов
static PCCERT_CONTEXT pRecipientCert = NULL;
static char *szDName = NULL;              // DName сертификата

int main(void)
{
    // Объявление и инициализация переменных. Они получают указатель на
    // сообщение, которое будет зашифровано. В данном коде создается сообщение,
    // получается указатель на него.

    BYTE pbContent[] = "Security is our business"; // Сообщение
    DWORD cbContent = sizeof(pbContent);           // Длина сообщения, включая конечный 0

    CRYPT_ALGORITHM_IDENTIFIER EncryptAlgorithm;
    CRYPT_ENCRYPT_MESSAGE_PARA EncryptParams;

    BYTE*    pbEncryptedBlob = NULL;
    DWORD    cbEncryptedBlob;

    printf("source message: %s\n", pbContent);
    printf("message length: %d bytes \n", cbContent);

    // Получение дескриптора криптографического провайдера.
    if(!CryptAcquireContext(
        &hCryptProv,         // Адрес возврашаемого дескриптора.
        0,                // Используется имя текущего зарегестрированного пользователя.
        NULL,                // Используется провайдер по умолчанию.
        PROV_GOST_2012_256,   // Необходимо для зашифрования и подписи.
        CRYPT_VERIFYCONTEXT))                // Никакие флаги не нужны.
    {
        HandleError("Cryptographic context could not be acquired.");
    }
    printf("CSP has been acquired. \n");

    // Открытие системного хранилища сертификатов.
    hStoreHandle = CertOpenSystemStore(hCryptProv, "MY");

    if(!hStoreHandle)
    {
        HandleError( "Error getting store handle.");
    }
    printf("The MY store is open. \n");

    // Получение указателя на сертификат получателя с помощью
    // функции GetRecipientCert.
    pRecipientCert = GetRecipientCert(hStoreHandle);

    if(!pRecipientCert)
    {
        printf("No certificate with a CERT_KEY_CONTEXT_PROP_ID \n");
        printf("property and an AT_KEYEXCHANGE private key available. \n");
        printf("While the message could be encrypted, in this case, \n");
        printf("it could not be decrypted in this program. \n");
        printf("For more information, see the documentation for \n");
        printf("CrypteEncryptMessage and CryptDecryptMessage.\n\n");
        HandleError( "No Certificate with AT_KEYEXCHANGE key in store.");
    }
    GetCertDName(&pRecipientCert->pCertInfo->Subject, &szDName);
    printf("A recipient's certificate has been acquired: %s\n", szDName);

    // Инициализация структуры с нулем.
    memset(&EncryptAlgorithm, 0, sizeof(CRYPT_ALGORITHM_IDENTIFIER));
    //EncryptAlgorithm.pszObjId = OID_CipherVar_Default;
    EncryptAlgorithm.pszObjId = szOID_CP_GOST_28147;

    // Инициализация структуры CRYPT_ENCRYPT_MESSAGE_PARA.
    memset(&EncryptParams, 0, sizeof(CRYPT_ENCRYPT_MESSAGE_PARA));
    EncryptParams.cbSize =  sizeof(CRYPT_ENCRYPT_MESSAGE_PARA);
    EncryptParams.dwMsgEncodingType = MY_ENCODING_TYPE;
    EncryptParams.hCryptProv = hCryptProv;
    EncryptParams.ContentEncryptionAlgorithm = EncryptAlgorithm;

    // Вызов функции CryptEncryptMessage.
    if(!CryptEncryptMessage(
        &EncryptParams,
        1,
        &pRecipientCert,
        pbContent,
        cbContent,
        NULL,
        &cbEncryptedBlob))
    {
        HandleError( "Getting EncrypBlob size failed.");
    }
    printf("The encrypted message is %d bytes. \n", cbEncryptedBlob);

    // Распределение памяти под возвращаемый BLOB.
    pbEncryptedBlob = (BYTE*)malloc(cbEncryptedBlob);

    if(!pbEncryptedBlob)
        HandleError("Memory allocation error while encrypting.");

    // Повторный вызов функции CryptEncryptMessage для зашифрования содержимого.
    if(!CryptEncryptMessage(
        &EncryptParams,
        1,
        &pRecipientCert,
        pbContent,
        cbContent,
        pbEncryptedBlob,
        &cbEncryptedBlob))
    {
        HandleError("Encryption failed.");
    }
    printf( "Encryption succeeded. \n");

    // Вызов функции DecryptMessage, код которой описан после main, для расшифрования сообщения.
    DecryptMessage(pbEncryptedBlob, cbEncryptedBlob);

    CleanUp();
    return 0;
}

//  Определение функции DecryptMessage.
// Пример функции для расшифрования зашифрованного сообщения с
// использованием функции CryptDecryptMessage. ЕЕ параметрами являются
// pbEncryptedBlob, зашифрованное сообщение; cbEncryptedBlob, длина
// этого сообщения
void DecryptMessage(BYTE *pbEncryptedBlob, DWORD cbEncryptedBlob)
{
    DWORD cbDecryptedMessage;
    CRYPT_DECRYPT_MESSAGE_PARA  decryptParams;

    BYTE*  pbDecryptedMessage = NULL;

    // Получение указателя на зашифрованное сообщение, pbEncryptedBlob,
    // и его длину, cbEncryptedBlob. В этом примере они устанавливаются
    // как параметры совместно с  CSP и дескриптором открытого хранилища.
    // Просмотр зашифрованного BLOBа.
    char * ep = getenv("COLUMNS");
    int brk;
    int i;
    brk = ep ? atoi(ep) : 80;
    brk = ((brk <= 3) ? 80 : brk) / 3;

    printf("The encrypted string is: \n");
    for(i = 0; i < (int)cbEncryptedBlob; i++)
        printf("%02x%c",pbEncryptedBlob[i],(i%brk == (brk - 1))?'\n':' ');
    printf("\n");

    //   В этом примере дескриптор хранилище MY установлен как параметр.

    //   Инициализация структуры CRYPT_DECRYPT_MESSAGE_PARA.
    memset(&decryptParams, 0, sizeof(CRYPT_DECRYPT_MESSAGE_PARA));
    decryptParams.cbSize = sizeof(CRYPT_DECRYPT_MESSAGE_PARA);
    decryptParams.dwMsgAndCertEncodingType = MY_ENCODING_TYPE;
    decryptParams.cCertStore = 1;
    decryptParams.rghCertStore = &hStoreHandle;

    //  Расшифрование сообщения

    //  Вызов фнукции CryptDecryptMessage для получения возвращаемого размера данных.
    if(!CryptDecryptMessage(
        &decryptParams,
        pbEncryptedBlob,
        cbEncryptedBlob,
        NULL,
        &cbDecryptedMessage,
        NULL))
    {
        free(pbEncryptedBlob);
        HandleError( "Error getting decrypted message size");
    }
    printf("The size for the decrypted message is: %d.\n", cbDecryptedMessage);

    // Выделение памяти под возвращаемые расшифрованные данные.
    pbDecryptedMessage = (BYTE*)malloc(cbDecryptedMessage);
    if(!pbDecryptedMessage)
    {
        free(pbEncryptedBlob);
        HandleError("Memory allocation error while decrypting");
    }
    // Вызов функции CryptDecryptMessage для расшифрования данных.
    if(!CryptDecryptMessage(
        &decryptParams,
        pbEncryptedBlob,
        cbEncryptedBlob,
        pbDecryptedMessage,
        &cbDecryptedMessage,
        NULL))
    {
        free(pbEncryptedBlob);
        free(pbDecryptedMessage);
        HandleError("Error decrypting the message");
    }

    printf("Message Decrypted Successfully. \n");
    printf("The decrypted string is: %s\n", (LPSTR) pbDecryptedMessage);

    free(pbEncryptedBlob);
    free(pbDecryptedMessage);
}

// Проверка типа провайдера
static BOOL isGostType(DWORD dwProvType) {
    return (dwProvType == PROV_GOST_2001_DH || dwProvType == PROV_GOST_2012_256 || dwProvType == PROV_GOST_2012_512);
}

// GetRecipientCert перечисляет сертификаты в хранилище и находит
// первый сертификат, обладающий ключем AT_EXCHANGE. Если сертификат
// сертификат найден, то возвращается указатель на него.
PCCERT_CONTEXT GetRecipientCert(HCERTSTORE hCertStore)
{
    PCCERT_CONTEXT pCertContext = NULL;
    BOOL bCertNotFind = TRUE;
    DWORD dwSize = 0;
    CRYPT_KEY_PROV_INFO* pKeyInfo = NULL;
    DWORD PropId = CERT_KEY_PROV_INFO_PROP_ID;
    HCRYPTPROV hProv = 0;
    DWORD dwKeySpec = 0;
    BOOL  fFreeProv = FALSE;

    if(!hCertStore) return NULL;

    do
    {
        // Поиск сертификатов в хранилище до тех пор, пока не будет достигнут
        // конец хранилища, или сертификат с ключем AT_KEYEXCHANGE не будет найден.
        pCertContext = CertFindCertificateInStore(
            hCertStore, // Дескриптор хранилища, в котором будет осуществлен поиск.
            MY_ENCODING_TYPE,
            0,
            CERT_FIND_PROPERTY,
            &PropId,
            pCertContext);
        if ( !pCertContext )
            break;

        // Для простоты в этом коде реализован только поиск первого
        // вхождения ключа AT_KEYEXCHANGE. Во многих случаях, помимо
        // поиска типа ключа, осуществляется также поиск определенного
        // имени субъекта.

        // Однократный вызов функции CertGetCertificateContextProperty
        // для получения возврашенного размера структуры.
        if(!(CertGetCertificateContextProperty(
            pCertContext,
            CERT_KEY_PROV_INFO_PROP_ID,
            NULL,
            &dwSize)))
        {
            printf("Error getting key property.\n");
            return NULL;
        }

        //--------------------------------------------------------------
        // распределение памяти под возвращенную структуру.

        if(pKeyInfo)
            free(pKeyInfo);

        pKeyInfo = (CRYPT_KEY_PROV_INFO*)malloc(dwSize);

        if(!pKeyInfo)
        {
            HandleError("Error allocating memory for pKeyInfo.");
        }

        //--------------------------------------------------------------
        // Получение структуры информации о ключе.

        if(!(CertGetCertificateContextProperty(
            pCertContext,
            CERT_KEY_PROV_INFO_PROP_ID,
            pKeyInfo,
            &dwSize)))
        {
            HandleError("The second call to the function failed.");
        }

        //-------------------------------------------
        // Проверка члена dwKeySpec на расширенный ключ и типа провайдера
        if(pKeyInfo->dwKeySpec == AT_KEYEXCHANGE && isGostType(pKeyInfo->dwProvType))
        {
            //-------------------------------------------
            //попробуем открыть провайдер
            fFreeProv = FALSE;
            if ( CryptAcquireCertificatePrivateKey(pCertContext, CRYPT_ACQUIRE_COMPARE_KEY_FLAG, NULL, &hProv, &dwKeySpec, &fFreeProv))
            {
                HCRYPTKEY hKey = 0;
                if (CryptGetUserKey( hProv, dwKeySpec, &hKey ))
                {
                    bCertNotFind = FALSE;
                    CryptDestroyKey( hKey );
                }
                if (fFreeProv)
                    CryptReleaseContext( hProv, 0 );
            }
        }
    } while(bCertNotFind && pCertContext);

    if(pKeyInfo)
        free(pKeyInfo);

    if (bCertNotFind)
        return NULL;
    else
        return (pCertContext);
} // Конец определения GetRecipientCert

//----------------------------------------------------------------------------
// Получение имени из CERT_NAME_BLOB
void GetCertDName(PCERT_NAME_BLOB pNameBlob, char **pszName) {
    DWORD       cbName;

    cbName = CertNameToStr(
        X509_ASN_ENCODING, pNameBlob,
        CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG,
        NULL, 0);
    if (cbName <= 1)
        HandleError("CertNameToStr(NULL)");

    *pszName = (char *)malloc(cbName * sizeof(char));
    if (!*pszName)
        HandleError("Out of memory.");

    cbName = CertNameToStr(
        X509_ASN_ENCODING, pNameBlob,
        CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG,
        *pszName, cbName);
    if (cbName <= 1)
        HandleError("CertNameToStr(pbData)");
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Пример на запись открытого ключа в файл

Этот пример демонстрирует использование следующих функций
  • CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetUserKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptExportKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptDestroyKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptReleaseContext в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
// Данный пример демонстрирует экспортирование открытого ключа в файл.
// Эта программа используется для экспортирования как открытого ключа
// отправителя, так и открытого ключа получателя.
// Она необходима для работы таких программ, как зашифрование и
// расшифрование содержимого файла.
// В PUBLICKEYBLOB не является кроссплатформенной структурой и не защищает
// ключи, поэтому рекомендуется использовать сертификаты для обмена открытыми
// ключами. Сертификат также записывается в файл, если он есть в контейнере.
// Для корректной работы этой программы необходимо создать контейнер
// с именем, передаваемым параметром из командной строки.
// Контейнер может быть создан при помощи примера CreatingKeyContainer
// Замечание: под win32 рекомендуется использовать _s аналоги CRT функций.
//--------------------------------------------------------------------

static void WriteBlobToFile(FILE *file, BYTE *pbData, DWORD cbData);
static void HandleError(char *s);
static void CleanUp(void);

static HCRYPTPROV hProv = 0;            // Дескриптор CSP
static HCRYPTKEY hKey = 0;              // Дескриптор открытого ключа получателя
static FILE *Public = NULL;             // Файл для хранения открытого ключа
static BYTE *pbKeyBlob = NULL;          // Указатель на ключевой BLOB
static FILE *Cert = NULL;               // Файл для хранения сертификата
static BYTE *pbCertBlob = NULL; // Указатель BLOB сертификата
static char *szFileName = NULL;        // Имя файла для экспорта

int main(int argc, char *argv[])
{
    DWORD cbKeyBlob;            // Длина ключевого BLOBа
    DWORD cbCertBlob;           // Длина BLOBа сертификата
    char  *szCont = argv[1];    // Короткое имя контейнера

    if (argc < 2 || strchr(szCont, '\\'))
        HandleError("Short container name required.");

    // Получение дескриптора контейнера с именем szCont,
    // находящегося в рамках провайдера.
    if(CryptAcquireContext(
        &hProv,
        szCont,
        NULL,
        PROV_GOST_2012_256,
        0))
    {
        printf("The key container \"%s\" has been acquired.\n", szCont);
    }
    else
    {
        HandleError("Error during CryptAcquireContext.");
    }

    //--------------------------------------------------------------------
    // Получение дескриптора открытого ключа.

    if(CryptGetUserKey(
        hProv,
        AT_KEYEXCHANGE,
        &hKey))
    {
        printf("The public key has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptGetUserKey public key.");
    }

    // Запись открытого ключа в ключевой BLOB.
    // Определение размера BLOBа открытого ключа и распределение памяти.
    if(CryptExportKey(
        hKey,
        0,
        PUBLICKEYBLOB,
        0,
        NULL,
        &cbKeyBlob))
    {
        printf("Size of the BLOB for the public key determined. \n");
    }
    else
    {
        HandleError("Error computing BLOB length.");
    }

    pbKeyBlob = (BYTE*)malloc(cbKeyBlob);
    if(!pbKeyBlob)
    {
        HandleError("Out of memory. \n");
    }

    // Экспортирование открытого ключа в BLOB открытого ключа.
    if(CryptExportKey(
        hKey,
        0,
        PUBLICKEYBLOB,
        0,
        pbKeyBlob,
        &cbKeyBlob))
    {
        printf("Contents have been written to the BLOB. \n");
    }
    else
    {
        HandleError("Error during CryptExportKey.");
    }

    szFileName = malloc((strlen(szCont) + 5) * sizeof(char));
    if(!szFileName)
    {
        HandleError("Out of memory. \n");
    }
    strcpy(szFileName, szCont);
    strcat(szFileName, ".pub");
    WriteBlobToFile(Public, pbKeyBlob, cbKeyBlob);

    // Получение сертификата ключа из контейнера (если он есть)
    if(CryptGetKeyParam(
        hKey,
        KP_CERTIFICATE,
        NULL,
        &cbCertBlob,
        0))
    {
        pbCertBlob = malloc(cbCertBlob);
        if(!pbCertBlob)
        {
            HandleError("Out of memory. \n");
        }
        if(CryptGetKeyParam(
            hKey,
            KP_CERTIFICATE,
            pbCertBlob,
            &cbCertBlob,
            0))
        {
            printf("Got certificate from container.\n");
        }
        else
        {
            HandleError("Error during CryptGetKeyParam.");
        }
        strcpy(szFileName, szCont);
        strcat(szFileName, ".cer");
        WriteBlobToFile(Cert, pbCertBlob, cbCertBlob);
    }
    else
    {
        printf("No certificate in container.\n");
    }

    CleanUp();

    printf("The program ran to completion without error. \n");
    return 0;
}

void WriteBlobToFile(FILE *file, BYTE *pbData, DWORD cbData)
{
    // Открытие файла на запись в него BLOB-а
    //if(!fopen_s(&file, szFileName, "r+b" ))
    if((file = fopen(szFileName, "wb")))
    {
        printf("The file '%s' was opened\n", szFileName);
    }
    else
    {
        HandleError("Problem opening the file\n");
    }

    // Запись BLOB-а в файл
    if(fwrite(pbData, 1, cbData, file))
    {
        printf("The public key was written to the '%s'\n", szFileName);
    }
    else
    {
        fclose(file);
        HandleError("The public key can not be written to file.\n");
    }

    fclose(file);
}

void CleanUp(void)
{
    if(Public)
        fclose (Public);

    if(Cert)
        fclose (Cert);

    // Освобождение памяти, используемой ключевым BLOBом.
    free(pbKeyBlob);

    // Освобождение памяти, используемой BLOBом сертификата.
    free(pbCertBlob);

    // Освобождени памяти под имя файла
    free(szFileName);

    // Уничтожение дескриптора открытого ключа.
    if(hKey)
        CryptDestroyKey(hKey);

    // Освобождение дескриптора провайдера.
    if(hProv)
        CryptReleaseContext(hProv, 0);
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Пример на зашифрование файла

Этот пример демонстрирует использование следующих функций
  • CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetUserKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptExportKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptImportKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptGenKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetKeyParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptEncrypt в MS CryptoAPI 2.0 World Wide Web link
  • CryptDestroyKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptReleaseContext в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
// В данном примере производится зашифрование файла на открытом ключе
// получателя.

// Для корректной работы данного примера предварительно необходимо
// записать открытый ключ получателя в файл "Responder.pub" при помощи
// примера ExportInFile.
// Также предварительно необходимо создать файл, подлежаший зашифрованию,
// с именем "source.txt".
// Следует сделить за тем, чтобы контейнеры "Sender" и "Responder",
// используемые в программах ExportInFile, EncryptFile и DecryptFile на момент
// выполнения этих программ существовали.
// Замечание: под win32 рекомендуется использовать _s аналоги CRT функций.
//--------------------------------------------------------------------

#define BLOCK_LENGTH 4096

static void LoadPublicKey(BYTE *pbBlob, DWORD *pcbBlob, char *szCertFile, char *szKeyFile);
static void HandleError(char *s);
static void CleanUp(void);

static HCRYPTPROV hProv = 0;            // Дескриптор CSP
static HCRYPTKEY hKey = 0;              // Дескриптор закрытого ключа
static HCRYPTKEY hSessionKey = 0;       // Дескриптор сессионного ключа
static HCRYPTKEY hAgreeKey = 0;        // Дескриптор ключа согласования

static FILE *certf=NULL;                // Файл, в котором хранится сертификат
static FILE *publicf=NULL;              // Файл, в котором хранится открытый ключ
static FILE *source=NULL;               // Исходный файл
static FILE *Encrypt=NULL;              // Зашифрованный файл
static FILE *session_SV=NULL;// Файл для хранения сессионного ключа (вектор инициализации)
static FILE *session_EncryptedKey=NULL;// Файл для хранения сессионного ключа (зашифрованный ключ)
static FILE *session_MacKey=NULL;       // Файл для хранения сессионного ключа (имита)
static FILE *vectorf=NULL;              // Файл для хранения вектора инициализации
static FILE *EncryptionParam;           // Файл для хранения неменяемой части блоба

static BYTE *pbKeyBlobSimple = NULL;   // Указатель на сессионный ключевой BLOB
static BYTE *pbIV = NULL;               // Вектор инициализации сессионного ключа

#define MAX_PUBLICKEYBLOB_SIZE 200

int main(void)
{
    BYTE  pbKeyBlob[MAX_PUBLICKEYBLOB_SIZE];    // Указатель на ключевой BLOB
    DWORD dwBlobLen = MAX_PUBLICKEYBLOB_SIZE;   // Длина ключевого BLOBа
    DWORD dwBlobLenSimple;      // Длина сессионного ключевого BLOBа

    BYTE pbContent[BLOCK_LENGTH];       // Указатель на содержимое исходного файла
    DWORD cbContent = 0;        // Длина содержимого
    DWORD dwIV = 0;             // Длина вектора инициализации
    DWORD bufLen = sizeof(pbContent);   // Длина буфера
    ALG_ID ke_alg = CALG_PRO12_EXPORT; // алгоритм ключа согласования
    DWORD cbEncryptionParamSetStandart; // длина неизменяемой части блоба

    // Открытие файла, который будет зашифрован.
    //if(!fopen_s(&source, "source.txt", "r+b" ))
    if(!(source = fopen("source.txt", "rb")))
        HandleError( "Problem opening the file 'source.txt'\n" );
    printf( "The file 'source.txt' was opened\n" );

    // Открытие файла, в который будет производится запись зашифрованного файла.
    //if(!fopen_s(&Encrypt, "encrypt.bin", "wb"))
    if(!(Encrypt = fopen("encrypt.bin", "wb")))
        HandleError( "Problem opening the file 'encrypt.bin'\n" );
    printf( "The file 'encrypt.bin' was opened\n" );

    // Открытие файла, в который производится запись синхропосылки.
    //if(!fopen_s(&session_SV, "session_SV.bin", "wb"))
    if(!(session_SV = fopen("session_SV.bin", "wb")))
        HandleError( "Problem opening the file 'session_SV.bin'\n" );
    printf( "The file 'session_SV.bin' was opened\n" );

    // Открытие файла, в который производится запись сессионного ключа.
    //if(!fopen_s(&session_EncryptedKey, "session_EncryptedKey.bin", "wb"))
    if(!(session_EncryptedKey = fopen("session_EncryptedKey.bin", "wb")))
        HandleError( "Problem opening the file 'session_EncryptedKey.bin'\n" );
    printf( "The file 'session_EncryptedKey.bin' was opened\n" );

    // Открытие файла, в который производится запись MAC сессионного ключа.
    //if(!fopen_s(&session_MacKey, "session_MacKey.bin", "wb" ))
    if(!(session_MacKey = fopen("session_MacKey.bin", "wb")))
        HandleError( "Problem opening the file 'session_MacKey.bin'\n" );
    printf( "The file 'session_MacKey.bin' was opened\n" );

    // Открытие файла, в который производится запись вектора инициализации.
    //if(!fopen_s(&vectorf, "vector.bin", "wb" ))
    if(!(vectorf = fopen("vector.bin", "wb")))
        HandleError( "Problem opening the file 'vector.bin'\n" );
    printf( "The file 'vector.bin' was opened\n" );

    // Открытие файла, в который производится запись вектора инициализации.
    //if(!fopen_s(&vectorf, "vector.bin", "wb" ))
    if (!(EncryptionParam = fopen("EncryptionParam.bin", "wb")))
        HandleError("Problem opening the file 'EncryptionParam.bin'\n");
    printf("The file 'EncryptionParam.bin' was opened\n");

    // Получение дескриптора контейнера получателя с именем "Sender",
    // находящегося в рамках провайдера.
    if(CryptAcquireContext(
        &hProv,
        "Sender",
        NULL,
        PROV_GOST_2012_256,
        0))
    {
        printf("The key container \"Sender\" has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptAcquireContext.");
    }

    LoadPublicKey(pbKeyBlob, &dwBlobLen, "Responder.cer", "Responder.pub");

    // Получение дескриптора закрытого ключа отправителя.
    if(CryptGetUserKey(
        hProv,
        AT_KEYEXCHANGE,
        &hKey))
    {printf("The private key has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptGetUserKey private key.");
    }

    // Получение ключа согласования импортом открытого ключа получателя
    // на закрытом ключе отправителя.

    if(CryptImportKey(
        hProv,
        pbKeyBlob,
        dwBlobLen,
        hKey,
        0,
        &hAgreeKey))
    {
        printf("The responder public key has been imported. \n");
    }
    else
    {
        HandleError("Error during CryptImportKey public key.");
    }

    // Установление PRO12_EXPORT алгоритма ключа согласования
    if(CryptSetKeyParam(
        hAgreeKey,
        KP_ALGID,
        (LPBYTE)&ke_alg,
        0))
    {
        printf("PRO12_EXPORT agree key algorithm has been set. \n");
    }
    else
    {
        HandleError("Error during CryptSetKeyParam agree key.");
    }

    // Генерация сессионного ключа.
    if(CryptGenKey(
        hProv,
        CALG_G28147,
        CRYPT_EXPORTABLE,
        &hSessionKey))
    {
        printf("Original session key is created. \n");
    }
    else
    {
        HandleError("ERROR -- CryptGenKey.");
    }

    //--------------------------------------------------------------------
    // Зашифрование сессионного ключа.
    //--------------------------------------------------------------------

    //--------------------------------------------------------------------
    // Определение размера BLOBа сессионного ключа и распределение памяти.

    if(CryptExportKey(
        hSessionKey,
        hAgreeKey,
        SIMPLEBLOB,
        0,
        NULL,
        &dwBlobLenSimple))
    {
        printf("Size of the BLOB for the sender session key determined. \n");
    }
    else
    {
        HandleError("Error computing BLOB length.");
    }

    pbKeyBlobSimple = (BYTE*)malloc(dwBlobLenSimple);

    if(!pbKeyBlobSimple)
        HandleError("Out of memory. \n");

    // Зашифрование сессионного ключа на ключе Agree.

    if(CryptExportKey(
        hSessionKey,
        hAgreeKey,
        SIMPLEBLOB,
        0,
        pbKeyBlobSimple,
        &dwBlobLenSimple))
    {
        printf("Contents have been written to the BLOB. \n");
    }
    else
    {
        HandleError("Error during CryptExportKey.");
    }

    // Определение размера вектора инициализации сессионного ключа.
    if(CryptGetKeyParam(
        hSessionKey,
        KP_IV,
        NULL,
        &dwIV,
        0))
    {
        printf("Size of the IV for the session key determined. \n");
    }
    else
    {
        HandleError("Error computing IV length.");
    }

    pbIV = (BYTE*)malloc(dwIV);
    if (!pbIV)
        HandleError("Out of memory. \n");

    // Определение вектора инициализации сессионного ключа.
    if(CryptGetKeyParam(
        hSessionKey,
        KP_IV,
        pbIV,
        &dwIV,
        0))
    {
        printf( "CryptGetKeyParam succeeded. \n");
    }
    else
    {
        HandleError("Error during CryptGetKeyParam.");
    }

    //--------------------------------------------------------------------
    // Запись вектора инициализации в файл.

    if(fwrite(
        pbIV,
        1,
        dwIV,
        vectorf))
    {
        printf( "The IV was written to the 'vector.bin'\n" );
    }
    else
    {
        HandleError( "The IV can not be written to the 'vector.bin'\n" );
    }

    //--------------------------------------------------------------------
    // Запись зашифрованного сессионного ключа в файл.

    if(fwrite(
        ((CRYPT_SIMPLEBLOB*)pbKeyBlobSimple)->bSV,
        1,
        SEANCE_VECTOR_LEN,
        session_SV))
    {
        printf( "The session key was written to the 'session_SV.bin'\n" );
    }
    else
    {
        HandleError( "The session key can not be written to the 'session_SV.bin'\n" );
    }

    //--------------------------------------------------------------------
    // Запись зашифрованного сессионного ключа в файл.

    if(fwrite(
        ((CRYPT_SIMPLEBLOB*)pbKeyBlobSimple)->bEncryptedKey,
        1,
        G28147_KEYLEN,
        session_EncryptedKey))
    {
        printf( "The session key was written to the 'session.bin'\n" );
    }
    else
    {
        HandleError( "The session key can not be written to the 'session.bin'\n" );
    }

    //--------------------------------------------------------------------
    // Запись зашифрованного сессионного ключа в файл.

    if(fwrite(
        ((CRYPT_SIMPLEBLOB*)pbKeyBlobSimple)->bMacKey,
        1,
        EXPORT_IMIT_SIZE,
        session_MacKey))
    {
        printf( "The session key was written to the 'session.bin'\n" );
    }
    else
    {
        HandleError( "The session key can not be written to the 'session.bin'\n" );
    }

    if (((CRYPT_SIMPLEBLOB*)pbKeyBlobSimple)->bEncryptionParamSet[0] != 0x30)
        HandleError("The EncryptionParam can not be written to the 'EncryptionParam.bin' - first byte is not 0x30\n");
    //CryptDecodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_NAME, );
    cbEncryptionParamSetStandart = (DWORD)((CRYPT_SIMPLEBLOB*)pbKeyBlobSimple)->bEncryptionParamSet[1] + sizeof((CRYPT_SIMPLEBLOB*)pbKeyBlobSimple)->bEncryptionParamSet[0] + sizeof((CRYPT_SIMPLEBLOB*)pbKeyBlobSimple)->bEncryptionParamSet[1];
    //--------------------------------------------------------------------
    // Запись неизменяемой части блоба в файл.

    if (fwrite(
        ((CRYPT_SIMPLEBLOB*)pbKeyBlobSimple)->bEncryptionParamSet,
        1,
        cbEncryptionParamSetStandart,
        EncryptionParam))
    {
        printf("The EncryptionParam was written to the 'EncryptionParam.bin'\n");
    }
    else
    {
        HandleError("The EncryptionParam can not be written to the 'EncryptionParam.bin'\n");
    }

    //--------------------------------------------------------------------
    // Чтение  файла, который будет зашифрован блоками по 4 КБ. Зашифрование
    // прочитанного блока и запись его в файл "encrypt.bin".
    //--------------------------------------------------------------------

    do
    {
        cbContent = (DWORD)fread(pbContent, 1, BLOCK_LENGTH, source);
        if(cbContent)
        {
            BOOL bFinal = feof(source);
            // Зашифрование прочитанного блока на сессионном ключе.
            if(CryptEncrypt(
                hSessionKey,
                0,
                bFinal,
                0,
                pbContent,
                &cbContent,
                bufLen))
            {
                printf( "Encryption succeeded. \n");
                // Запись зашифрованного блока в файл.
                if(fwrite(
                    pbContent,
                    1,
                    cbContent,
                    Encrypt))
                {
                    printf( "The encrypted content was written to the 'encrypt.bin'\n" );
                }
                else
                {
                    HandleError( "The encrypted content can not be written to the 'encrypt.bin'\n" );
                }
            }
            else
            {
                HandleError("Encryption failed.");
            }
        }
        else
        {
            HandleError( "Problem reading the file 'source.txt'\n" );
        }
    }
    while (!feof(source));

    CleanUp();

    printf("The program ran to completion without error. \n");
    return 0;
}

// Загрузка PUBLICKEYBLOB из сертификата, если он есть, (предпочтительно) или
// из блоба, записанного в файл.
void LoadPublicKey(BYTE *pbBlob, DWORD *pcbBlob, char *szCertFile, char *szKeyFile)
{
    // Открытие файла, в котором содержится открытый ключ получателя.
    //if(fopen_s(&certf, szCertFile, "r+b" ))
    if((certf = fopen(szCertFile, "rb"))) {
        DWORD cbCert = 2000;
        BYTE  pbCert[2000];
        PCCERT_CONTEXT pCertContext = NULL;
        HCRYPTKEY hPubKey;
        printf( "The file '%s' was opened\n", szCertFile );

        cbCert = (DWORD)fread(pbCert, 1, cbCert, certf);
        if(!cbCert)
            HandleError( "Failed to read certificate\n" );
        printf( "Certificate was read from the '%s'\n", szCertFile );

        pCertContext = CertCreateCertificateContext (
            X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, pbCert, cbCert);
        if (!pCertContext) {
            HandleError( "CertCreateCertificateContext" );
        }

        // Импортируем открытый ключ
        if (CryptImportPublicKeyInfoEx(
            hProv,
            X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
            &(pCertContext->pCertInfo->SubjectPublicKeyInfo),
            0,
            0,
            NULL,
            &hPubKey))
        {
            printf("Public key imported from cert file\n");
        } else {
            CertFreeCertificateContext(pCertContext);
            HandleError( "CryptImportPublicKeyInfoEx" );
        }
        CertFreeCertificateContext(pCertContext);

        // Экспортируем его в BLOB
        if (CryptExportKey(
            hPubKey,
            0,
            PUBLICKEYBLOB,
            0,
            pbBlob,
            pcbBlob))
        {
            printf("Public key exported to blob\n");
        }
        else
        {
            HandleError( "CryptExportKey" );
        }
    } else {
        // Открытие файла, в котором содержится открытый ключ получателя.
        //if(!fopen_s(&publicf, szKeyFile, "r+b" ))
        if(!(publicf = fopen(szKeyFile, "rb")))
            HandleError( "Problem opening the public key blob file\n" );
        printf( "The file '%s' was opened\n", szKeyFile );

        *pcbBlob = (DWORD)fread(pbBlob, 1, *pcbBlob, publicf);
        if(!*pcbBlob)
            HandleError( "Failed to read key blob file\n" );
        printf( "Key blob was read from the '%s'\n", szKeyFile );
    }
}

void CleanUp(void)
{
    if(source)
        fclose (source);
    if(Encrypt)
        fclose (Encrypt);
    if(session_SV)
        fclose (session_SV);
    if(session_EncryptedKey)
        fclose (session_EncryptedKey);
    if(session_MacKey)
        fclose (session_MacKey);
    if(vectorf)
        fclose (vectorf);
    if(certf)
        fclose (certf);
    if(publicf)
        fclose (publicf);
    if (EncryptionParam)
        fclose(EncryptionParam);

    // Уничтожение дескриптора закрытого ключа.
    if(hKey)
        CryptDestroyKey(hKey);

    // Уничтожение дескриптора сессионного ключа.
    if(hSessionKey)
        CryptDestroyKey(hSessionKey);

    // Уничтожение дескриптора ключа согласования.
    if(hAgreeKey)
        CryptDestroyKey(hAgreeKey);

    // Освобождение дескриптора провайдера.
    if(hProv)
        CryptReleaseContext(hProv, 0);

    if(pbKeyBlobSimple)
        free(pbKeyBlobSimple);
    if(pbIV)
        free(pbIV);
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Пример на расшифрование файла

Этот пример демонстрирует использование следующих функций
  • CryptAcquireContext в MS CryptoAPI 2.0 World Wide Web link
  • CryptGetUserKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptImportKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptSetKeyParam в MS CryptoAPI 2.0 World Wide Web link
  • CryptDecrypt в MS CryptoAPI 2.0 World Wide Web link
  • CryptDestroyKey в MS CryptoAPI 2.0 World Wide Web link
  • CryptReleaseContext в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
// Данный пример демонстрирует расшифрование файла на сессионном ключе.

// Для корректной работы этого примера передаваемые ему входные данные
// должны являться результатом работы примера EncryptFile.
// Зашифрованный сессионный ключ содержится в файле "session_EncryptedKey.bin",
// синхропосылка для согласования ключей - в "session_SV.bin",
// MAC зашифрованного сессионного ключа - в "session_MacKey.bin".
// Для его расшифрования необходим открытый ключ отправителя, содержащийся
// в файле "Sender.pub" (данный файл создается при выполнении примера
// ExportInFile).
// Для корректной работы этой программы необходимо получить зашифрованный
// файл с именем "encrypt.bin". Для правильного расшифрования файла
// необходим вектор инициализации, который хранится в файле "vector.bin".
// Расшифрование производится в файл "destination.txt".
// Следует сделить за тем, чтобы контейнеры "Sender" и "Responder",
// используемые в программах ExportInFile, EncryptFile и DecryptFile на момент
// выполнения этих программ существовали.
// Замечание: под win32 рекомендуется использовать _s аналоги CRT функций.
//--------------------------------------------------------------------

#define BLOCK_LENGTH 4096

static void LoadPublicKey(BYTE *pbBlob, DWORD *pcbBlob, char *szCertFile, char *szKeyFile);
static void CleanUp(void);
static void HandleError(char *s);

static HCRYPTPROV hProv = 0;            // Дескриптор CSP
static HCRYPTKEY hKey = 0;              // Дескриптор закрытого ключа
static HCRYPTKEY hSessionKey = 0;       // Дескриптор сессионного ключа
static HCRYPTKEY hAgreeKey = 0;        // Дескриптор ключа согласования

static FILE *Encrypt=NULL;              // Зашифрованный файл
static FILE *certf=NULL;                // Файл, в котором хранится сертификат
static FILE *publicf=NULL;              // Файл, в котором хранится открытый ключ
static FILE *session_SV=NULL;// Файл для хранения сессионного ключа (вектор инициализации)
static FILE *session_EncryptedKey=NULL;// Файл для хранения сессионного ключа (зашифрованный ключ)
static FILE *session_MacKey=NULL;       // Файл для хранения сессионного ключа (имита)
static FILE *vectorf=NULL;              // Файл для хранения вектора инициализации
static FILE *destination=NULL;          // Расшифрованный файл
static FILE *EncryptionParam=NULL;           // Файл для хранения неменяемой части блоба

#define MAX_PUBLICKEYBLOB_SIZE 200

int main(void)
{
    BYTE  pbKeyBlob[MAX_PUBLICKEYBLOB_SIZE];    // Указатель на ключевой BLOB
    DWORD dwBlobLen = MAX_PUBLICKEYBLOB_SIZE;   // Длина ключевого BLOBа
    BYTE *pbKeyBlobSimple = NULL;  // Указатель на сессионный ключевой BLOB
    DWORD cbBlobLenSimple;      // Длина сессионного ключевого BLOBа
    BYTE pbIV[100];             // Вектор инициализации сессионного ключа
    DWORD dwIV = 0;             // Длина вектора инициализации
    BYTE pbContent[BLOCK_LENGTH];       // Указатель на содержимое зашифрованного файла
    DWORD cbContent = 0;        // Длина содержимого
    ALG_ID ke_alg = CALG_PRO12_EXPORT; // алгоритм ключа согласования
    CRYPT_SIMPLEBLOB_HEADER tSimpleBlobHeaderStandart;
    DWORD dwBytesRead;
    BYTE *pbEncryptionParamSetStandart; //неменяемая часть блоба
    DWORD cbEncryptionParamSetStandart; //длина неменяемой части блоба

    tSimpleBlobHeaderStandart.BlobHeader.aiKeyAlg = CALG_G28147;
    tSimpleBlobHeaderStandart.BlobHeader.bType = SIMPLEBLOB;
    tSimpleBlobHeaderStandart.BlobHeader.bVersion = BLOB_VERSION;
    tSimpleBlobHeaderStandart.BlobHeader.reserved = 0;
    tSimpleBlobHeaderStandart.EncryptKeyAlgId = CALG_G28147;
    tSimpleBlobHeaderStandart.Magic = G28147_MAGIC;

    // Открытие файла, в котором хранится зашифрованный файл.
    //if(!fopen_s( &Encrypt, "encrypt.bin", "r+b" ))
    if(!(Encrypt = fopen("encrypt.bin", "r+b" )))
        HandleError( "Problem opening the file 'encrypt.bin'\n" );
    printf( "The file 'encrypt.bin' was opened\n" );

    // Открытие файла, в который производится запись сессионного ключа.
    if(!(session_SV = fopen("session_SV.bin", "r+b")))
        HandleError( "Problem opening the file 'session_SV.bin'\n" );
    printf( "The file 'session_SV.bin' was opened\n" );

    // Открытие файла, в который производится запись сессионного ключа.
    if(!(session_EncryptedKey = fopen("session_EncryptedKey.bin", "r+b")))
        HandleError( "Problem opening the file 'session_EncryptedKey.bin'\n" );
    printf( "The file 'session_EncryptedKey.bin' was opened\n" );

    // Открытие файла, в который производится запись сессионного ключа.
    if(!(session_MacKey = fopen("session_MacKey.bin", "r+b")))
        HandleError( "Problem opening the file 'session_MacKey.bin'\n" );
    printf( "The file 'session_MacKey.bin' was opened\n" );

    // Открытие файла, в котором хранится вектор инициализации.
    //if(!fopen_s(&vectorf, "vector.bin", "r+b" ))
    if(!(vectorf = fopen("vector.bin", "r+b")))
        HandleError( "Problem opening the file 'vector.bin'\n" );
    printf( "The file 'vector.bin' was opened\n" );

    // Открытие файла, в который будет записан расшифрованный файл.
    //if(!fopen_s(&destination, "destination.txt", "w+b" ))
    if(!(destination = fopen("destination.txt", "w+b" )))
        HandleError( "Problem opening the file 'destination.txt'\n" );
    printf( "The file 'destination.txt' was opened\n" );

    // Открытие файла, в котором хранится неменяемая часть блоба.
    //if(!fopen_s(&vectorf, "vector.bin", "r+b" ))
    if (!(EncryptionParam = fopen("EncryptionParam.bin", "r+b")))
        HandleError("Problem opening the file 'EncryptionParam.bin'\n");
    printf("The file 'EncryptionParam.bin' was opened\n");

    // Чтение  вектора инициализации из файла.
    dwIV = (DWORD)fread(pbIV, 1, 100, vectorf);
    if(!dwIV)
        HandleError( "The IV can not be reading from the 'vector.bin'\n" );
    printf( "The IV was read from the 'vector.bin'\n" );

    // Получение дескриптора контейнера получателя с именем "Responder",
    // находящегося в рамках провайдера.
    if(!CryptAcquireContext(
        &hProv,
        "Responder",
        NULL,
        PROV_GOST_2012_256,
        0))
    {
        HandleError("Error during CryptAcquireContext");
    }
    printf("The key container \"Responder\" has been acquired. \n");

    // obtain file size:
    fseek(EncryptionParam, 0, SEEK_END);
    cbEncryptionParamSetStandart = sizeof(char)*ftell(EncryptionParam);
    rewind(EncryptionParam);
    // allocate memory to contain the whole file:
    pbEncryptionParamSetStandart = (BYTE*)malloc(cbEncryptionParamSetStandart);
    if (pbEncryptionParamSetStandart == NULL)
        HandleError("Out of memory. \n");
    // copy the file into the buffer:
    dwBytesRead = (DWORD)fread(pbEncryptionParamSetStandart, 1, cbEncryptionParamSetStandart, EncryptionParam);
    if (dwBytesRead != cbEncryptionParamSetStandart)
        HandleError("The EncryptionParam can not be reading from the 'EncryptionParam.bin'\n");

    cbBlobLenSimple = cbEncryptionParamSetStandart;
    cbBlobLenSimple += (sizeof(CRYPT_SIMPLEBLOB_HEADER)+SEANCE_VECTOR_LEN + G28147_KEYLEN + EXPORT_IMIT_SIZE);// +sizeof(pbEncryptionParamSetStandart);
    pbKeyBlobSimple = malloc(cbBlobLenSimple);
    if(!pbKeyBlobSimple)
        HandleError("Out of memory. \n");

    memcpy(&((CRYPT_SIMPLEBLOB*)pbKeyBlobSimple)->tSimpleBlobHeader, &tSimpleBlobHeaderStandart, sizeof(CRYPT_SIMPLEBLOB_HEADER)); //копируем неменяемый хедер в блобе

    // Чтение  сесcионного ключа из файла.
    dwBytesRead = (DWORD)fread(((CRYPT_SIMPLEBLOB*)pbKeyBlobSimple)->bSV, 1, SEANCE_VECTOR_LEN, session_SV);
    if(!dwBytesRead)
        HandleError( "The session key can not be reading from the 'session_SV.bin'\n" );
    printf( "The session key was read from the 'session_SV.bin'\n" );

    // Чтение  сесcионного ключа из файла.
    dwBytesRead = (DWORD)fread(((CRYPT_SIMPLEBLOB*)pbKeyBlobSimple)->bEncryptedKey, 1, G28147_KEYLEN, session_EncryptedKey);
    if(!dwBytesRead)
        HandleError( "The session key can not be reading from the 'session_EncryptedKey.bin'\n" );
    printf( "The session key was read from the 'session_EncryptedKey.bin'\n" );

    memcpy(((CRYPT_SIMPLEBLOB*)pbKeyBlobSimple)->bEncryptionParamSet, pbEncryptionParamSetStandart, cbEncryptionParamSetStandart); //копируем неменяемую ASN структуру

    // Чтение  сесcионного ключа из файла.
    dwBytesRead = (DWORD)fread(((CRYPT_SIMPLEBLOB*)pbKeyBlobSimple)->bMacKey, 1, EXPORT_IMIT_SIZE, session_MacKey);
    if(!dwBytesRead)
        HandleError( "The session key can not be reading from the 'session_MacKey.bin'\n" );
    printf( "The session key was read from the 'session_MacKey.bin'\n" );

    LoadPublicKey(pbKeyBlob, &dwBlobLen, "Sender.cer", "Sender.pub");

    // Получение дескриптора закрытого ключа получателя.
    if(CryptGetUserKey(
        hProv,
        AT_KEYEXCHANGE,
        &hKey))
    {
        printf("The private key has been acquired. \n");
    }
    else
    {
        HandleError("Error during CryptGetUserKey private key.");
    }

    // Получение ключа согласования импортом открытого ключа отправителя
    // на закрытом ключе получателя.
    if(CryptImportKey(
        hProv,
        pbKeyBlob,
        dwBlobLen,
        hKey,
        0,
        &hAgreeKey))
    {
        printf("The sender public key has been imported. \n");
    }
    else
    {
        HandleError("Error during CryptImportKey public key.");
    }

    // Установление PRO12_EXPORT алгоритма ключа согласования
    if(CryptSetKeyParam(
        hAgreeKey,
        KP_ALGID,
        (LPBYTE)&ke_alg,
        0))
    {
        printf("PRO12_EXPORT agree key algorithm has been set. \n");
    }
    else
    {
        HandleError("Error during CryptSetKeyParam agree key.");
    }

    // Получение сессионного ключа импортом зашифрованного сессионного ключа
    // на ключе Agree.
    if(CryptImportKey(
        hProv,
        pbKeyBlobSimple,
        cbBlobLenSimple,
        hAgreeKey,
        0,
        &hSessionKey))
    {
        printf("The session key has been imported. \n");
    }
    else
    {
        HandleError("Error during CryptImportKey session key.");
    }

    // Установка вектора инициализации - без него первые 8 байт
    // расшифруются неправильно.
    if(!CryptSetKeyParam(
        hSessionKey,
        KP_IV,
        pbIV,
        0))
    {
        HandleError("Error during CryptSetKeyParam.");
    }
    printf( "CryptSetKeyParam succeeded. \n");

    // Чтение  зашифрованного файла блоками по 4 КБ. Расшифрование прочитанного
    // блока и запись его в файл "destination.txt".
    do
    {
        cbContent = (DWORD)fread(pbContent, 1, BLOCK_LENGTH, Encrypt);
        if(cbContent)
        {
            BOOL bFinal = feof(Encrypt);
            // Расшифрование прочитанного блока на сессионном ключе.
            if(CryptDecrypt(
                hSessionKey,
                0,
                bFinal,
                0,
                pbContent,
                &cbContent))
            {
                printf( "Decryption succeeded. \n");
                // Запись расшифрованного блока в файл.
                if(fwrite(
                    pbContent,
                    1,
                    cbContent,
                    destination))
                {
                    printf( "The decrypted content was written to the 'destination.txt'\n" );
                }
                else
                {
                    HandleError( "The decrypted content can not be written to the 'destination.txt'\n" );
                }
            }
            else
            {
                HandleError("Decryption failed.");
            }
        }
        else
        {
            HandleError( "Problem reading the file 'encrypt.bin'\n" );
        }
    }
    while(!feof(Encrypt));

    CleanUp();

    printf("The program ran to completion without error. \n");
    free(pbEncryptionParamSetStandart);
    free(pbKeyBlobSimple);
    return 0;
}// Конец main

// Загрузка PUBLICKEYBLOB из сертификата, если он есть, (предпочтительно) или
// из блоба, записанного в файл.
void LoadPublicKey(BYTE *pbBlob, DWORD *pcbBlob, char *szCertFile, char *szKeyFile)
{
    // Открытие файла, в котором содержится открытый ключ получателя.
    //if(fopen_s(&certf, szCertFile, "r+b" ))
    if((certf = fopen(szCertFile, "rb"))) {
        DWORD cbCert = 2000;
        BYTE  pbCert[2000];
        PCCERT_CONTEXT pCertContext = NULL;
        HCRYPTKEY hPubKey;
        printf( "The file '%s' was opened\n", szCertFile );

        cbCert = (DWORD)fread(pbCert, 1, cbCert, certf);
        if(!cbCert)
            HandleError( "Failed to read certificate\n" );
        printf( "Certificate was read from the '%s'\n", szCertFile );

        pCertContext = CertCreateCertificateContext (
            X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, pbCert, cbCert);
        if (!pCertContext) {
            HandleError( "CertCreateCertificateContext" );
        }

        // Импортируем открытый ключ
        if (CryptImportPublicKeyInfoEx(
            hProv,
            X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
            &(pCertContext->pCertInfo->SubjectPublicKeyInfo),
            0,
            0,
            NULL,
            &hPubKey))
        {
            printf("Public key imported from cert file\n");
        } else {
            CertFreeCertificateContext(pCertContext);
            HandleError( "CryptImportPublicKeyInfoEx" );
        }
        CertFreeCertificateContext(pCertContext);

        // Экспортируем его в BLOB
        if (CryptExportKey(
            hPubKey,
            0,
            PUBLICKEYBLOB,
            0,
            pbBlob,
            pcbBlob))
        {
            printf("Public key exported to blob\n");
        }
        else
        {
            HandleError( "CryptExportKey" );
        }
    } else {
        // Открытие файла, в котором содержится открытый ключ получателя.
        //if(!fopen_s(&publicf, szKeyFile, "r+b" ))
        if(!(publicf = fopen(szKeyFile, "rb")))
            HandleError( "Problem opening the public key blob file\n" );
        printf( "The file '%s' was opened\n", szKeyFile );

        *pcbBlob = (DWORD)fread(pbBlob, 1, *pcbBlob, publicf);
        if(!*pcbBlob)
            HandleError( "Failed to read key blob file\n" );
        printf( "Key blob was read from the '%s'\n", szKeyFile );
    }
}

void CleanUp(void)
{
    if(Encrypt)
        fclose (Encrypt);
    if(session_SV)
        fclose (session_SV);
    if(session_EncryptedKey)
        fclose (session_EncryptedKey);
    if(session_MacKey)
        fclose (session_MacKey);
    if(vectorf)
        fclose (vectorf);
    if(destination)
        fclose (destination);
    if(certf)
        fclose (certf);
    if(publicf)
        fclose (publicf);
    if (EncryptionParam)
        fclose (EncryptionParam);

    // Уничтожение дескриптора закрытого ключа.
    if(hKey)
        CryptDestroyKey(hKey);

    // Уничтожение дескриптора сессионного ключа.
    if(hSessionKey)
        CryptDestroyKey(hSessionKey);

    // Уничтожение дескриптора ключа согласования.
    if(hAgreeKey)
        CryptDestroyKey(hAgreeKey);

    // Освобождение дескриптора провайдера.
    if(hProv)
        CryptReleaseContext(hProv, 0);
}

// Конец примера

    Требования:

    AIX: 5/6/7 или выше.
    FreeBSD: 7/8/9 или выше.
    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.
    Solaris: 10 или выше.
    Mac OSX: 10.7/8 или выше.
    iOS: 6/7 или выше.
    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.
    Ядро Windows NT: не поддерживает.


Примеры использования функций криптопровайдера для работы с XML-документом.

В данном разделе приводятся примеры, демонстрирующие использование функций криптопровайдера для работы с XML-документом.

  • Шаблон XML-документа на подпись
  • Шаблон XML-документа для создания двух подписей
  • Пример создания подписи XML-документа
  • Пример проверки подписи XML-документа
  • Пример создания и проверки двух подписей XML-документа


Шаблон XML-документа на подпись

Данный шаблон является обязательным шаблоном XML-документа, для которого осуществляется подпись.

<?xml version="1.0" encoding="UTF-8"?>
<ds:signatures xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:Signature Id="FirstSignature" >
  <ds:SignedInfo>
    <ds:CanonicalizationMethod
       Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
    <ds:SignatureMethod
    Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411"/>
    <ds:Reference URI="#obj"
      Type="http://www.w3.org/2000/09/xmldsig#;Object">
          <ds:DigestMethod
      Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411"/>
        <ds:DigestValue/>
    </ds:Reference>
  </ds:SignedInfo>
  <ds:SignatureValue />
  <ds:Object Id="obj" MimeType="text/xml">Hello, World!</ds:Object>
     <ds:KeyInfo></ds:KeyInfo>
</ds:Signature>

Требования:

Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше. Необходим MSXML 5.0.


Шаблон XML-документа для создания двух подписей

Данный шаблон является обязательным шаблоном XML-документа, для которого создаются две независимые подписи.

<?xml version="1.0" encoding="UTF-8"?>
<ds:signatures xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:Signature Id="FirstSignature" >
  <ds:SignedInfo>
    <ds:CanonicalizationMethod
       Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
    <ds:SignatureMethod
    Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411"/>
    <ds:Reference URI="#obj"
      Type="http://www.w3.org/2000/09/xmldsig#;Object">
          <ds:DigestMethod
      Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411"/>
        <ds:DigestValue/>
    </ds:Reference>
  </ds:SignedInfo>
  <ds:SignatureValue />
  <ds:Object Id="obj" MimeType="text/xml">Hello, World!</ds:Object>
     <ds:KeyInfo></ds:KeyInfo>
</ds:Signature>
<ds:Signature Id="SecondSignature">
  <ds:SignedInfo>
    <ds:CanonicalizationMethod
       Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
    <ds:SignatureMethod
    Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411"/>
    <ds:Reference URI="#obj"
      Type="http://www.w3.org/2000/09/xmldsig#;Object">
          <ds:DigestMethod
      Algorithm="http://www.w3.org/2001/04/xmldsig-more#gostr3411"/>
        <ds:DigestValue/>
    </ds:Reference>
  </ds:SignedInfo>
  <ds:SignatureValue />
     <ds:KeyInfo></ds:KeyInfo>
</ds:Signature>
</ds:signatures>

Требования:

Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше. Необходим MSXML 5.0.


Пример создания подписи XML-документа

Этот пример демонстрирует использование следующих функций
  • CertOpenStore в MS CryptoAPI 2.0 World Wide Web link
  • CertFindCertificateInStore в MS CryptoAPI 2.0 World Wide Web link
  • CertGetCertificateContextProperty в MS CryptoAPI 2.0 World Wide Web link
  • CertFreeCertificateContext в MS CryptoAPI 2.0 World Wide Web link
  • CertCloseStore в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
// Пример создания подписи документа MSXML 5.0 на ключе, получаемом по
// имени ключевого контейнера. Имя контейнера, в свою очередь, получается
// из расширенных свойств заданного сертификата.
// Данная программа имеет два аргумента командной строки:
// 1) Имя исходного XML-документа (документ должен соответствовать
// шаблону, приведенному в примере).
// 2) Имя сертификата.
// Подписанным (выходным) XML-документом является файл "out_signature.xml".
// Замечание: под win32 рекомендуется использовать _s аналоги CRT функций.
//--------------------------------------------------------------------

#include <atlbase.h>
#include "msxml5.h"

#define DSIGNS L"xmlns:ds='http://www.w3.org/2000/09/xmldsig#'"
#define OUTFILE L"out_signature.xml"

//-------------------------------------------------------------
// Объявление и инициализация переменных.

CComPtr<IXMLDOMDocument2> xmldoc;
CComPtr<IXMLDigitalSignatureEx> xmldsig;

bool initObjects(void);
bool LoadXML(VARIANT sigFile);
bool SetSignature(BSTR queryString);
bool SignXML(XMLDSIG_WRITEKEYINFO fwWriteKeyInfo, TCHAR* userName,
    VARIANT outfile);
void HandleError(char *s);

//------------------------------------------------------------------------------
// Подпись XML-документа на основе сертификата.
//------------------------------------------------------------------------------
int _tmain(int argc, TCHAR **argv)
{
    // Инициализация COM библиотеки.
    if (FAILED(CoInitialize(NULL)))
        HandleError("can't initialize COM Lib");

    // Разбор командной строки.
    if(argc < 2)
        HandleError("usage: XMLSignForVerify test.xml certname\n");

    // Инициализация объектов.
    if(!initObjects())
        exit(-1);

    CComVariant sigFile(argv[1]);
    printf("Signing %S\n\n", sigFile.bstrVal);
    if(!LoadXML(sigFile))
        exit(-1);

    if(!SetSignature(CComBSTR(L".//ds:Signature")))
        exit(-1);

    // Подпись XML-документа.
    CComVariant outfile(OUTFILE);
    if (!SignXML(CERTIFICATES, argv[2], outfile))
        exit(-1);

    return 0;
}

//---------------------------------------------------------------------------
// Описание функции загрузки XML-документа.
//---------------------------------------------------------------------------

bool LoadXML(VARIANT sigFile)
{
    VARIANT_BOOL isSuccessful = VARIANT_FALSE;
    if(FAILED(xmldoc->load(sigFile, &isSuccessful)) || isSuccessful == VARIANT_FALSE)
    {
        printf("Can't load %S\n", sigFile.bstrVal);
        return false;
    }
    if (FAILED(xmldoc->setProperty(L"SelectionNamespaces", CComVariant(DSIGNS))))
    {
        printf("setProperty failed\n");
        return false;
    }
    return true;
}
// Конец описания функции LoadXML

//------------------------------------------------------------------------------
// Определение свойств подписи в соответствии с DOM узлом <ds:Signature>
// XML-документа.

bool SetSignature(BSTR queryString)
{
    CComPtr<IXMLDOMNode> signatureNode;
    if (FAILED(xmldoc->selectSingleNode(queryString, &signatureNode)))
    {
        printf("Failed to get Signature node.\n");
        return false;
    }
    if (FAILED(xmldsig->putref_signature(signatureNode)))
    {
        printf("Failed to set the signature property.\n");
        return false;
    }
    signatureNode.Release();
    // Попробуем тут же получить обратно и проверить
    if(FAILED(xmldsig->get_signature(&signatureNode)) || !signatureNode)
    {
        printf("Invalid signature template\n");
        return false;
    }
    return true;
}

//---------------------------------------------------------------------------
// Описание функции подписи XML-документа.
//
// Данная функция имеет параметр fwWriteKeyInfo, отвечающий
// за заполнение шаблона подписанного (выходного) XML-документа.
// Шаблон подписанного (выходного) XML-документа изначально включает в себя
// три пустых элемента: <ds:DigestValue>, <ds:SignatureValue>  и  <ds:KeyInfo>.
// Первые два заполняются после выполнения функции SignXML(fwWriteKeyInfo).
// Последний будет заполнен только в том случае, если функции
// в качестве параметра fwWriteKeyInfo передаётся KEYVALUE.
// Параметр не меняется, если fwWriteKeyInfo = NOKEYINFO и всё
// содержимое элементов очищается в случае  fwWriteKeyInfo = PURGE.
// Когда fwWriteKeyInfo = CERTIFICATES,  заполняется элемент <X509Data>
// при условии, что сертификат ключа, который используется, доступен.
//
// Также параметр fwWriteKeyInfo может представлять собой комбинацию
// перечисленных выше значений, объединённых знаком "|" :
// KEYVALUE | CERTIFICATES  - Добавляет значение ключа и сертификаты в <ds:KeyInfo>,
//                      не изменяя другие элементы.
// KEYVALUE | CERTIFICATES | PURGE - Сначала удаляет всё из <ds:KeyInfo>, а затем
//                      добавляет значение ключа и сертификаты.
// KEYVALUE | PURGE - Сначала удаляет всё из <ds:KeyInfo>,
//                      а  затем добавляет значение ключа.
// CERTIFICATES | PURGE - Сначала удаляет всё из <ds:KeyInfo>,
//                      а затем добавляет сертификаты.
//---------------------------------------------------------------------------

bool SignXML(XMLDSIG_WRITEKEYINFO fwWriteKeyInfo,
    TCHAR* userName, VARIANT outfile)
{
    if (fwWriteKeyInfo & CERTIFICATES)
        printf("Sign with fwWriteKeyInfo = CERTIFICATES:\n");

    HCERTSTORE hStore = NULL; // Дескритор хранилища сертификатов
    //------------------------------------------------------------------------------
    // Открытие хранилища сертификатов "MY" текущего пользователя.
    hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
        CERT_STORE_OPEN_EXISTING_FLAG |CERT_STORE_READONLY_FLAG |
        CERT_SYSTEM_STORE_CURRENT_USER, L"MY");
    if(!hStore)
    {
        HandleError("The store could not be opened!\n");
    }
    else
    {
        printf("The store is open!\n");
    }

    //-----------------------------------------------------------------
    // Получение сертификата с заданным именем из хранилища сертификатов.
    PCCERT_CONTEXT pContext = NULL ; // Контекст сертификата
    pContext = CertFindCertificateInStore(hStore,
        X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR_W,
        userName, NULL);
    if(pContext == NULL)
    {
        HandleError("There is no such a certificate in the store\n");
    }

    // Параметр для получения информации из свойств сертификата
    DWORD dwPropId = CERT_KEY_PROV_INFO_PROP_ID;
    DWORD cbData; // Длина буфера данных

    //--------------------------------------------------------------------------
    // Получение информации из расширенных свойств контекста сертификата.
    // Определение размера возвращаемых данных.
    if(CertGetCertificateContextProperty(pContext, dwPropId, NULL, &cbData))
    {
        printf("CertGetCertificateContextProperty was started for the 1-st time\n");
    }
    else
    {
        printf("CertGetCertificateContextProperty was started for the 1-st time\n");
        HandleError("It's impossible to get the certificate property!\n ");
    }

    //--------------------------------------------------------------------------
    // Указатель на структуру CRYPT_KEY_PROV_INFO, содержащую подробную информацию
    // о ключевом контейнере.
    CRYPT_KEY_PROV_INFO *pbData;

    //-------------------------------------------------------------------------
    // Выделение памяти.
    if(pbData = (CRYPT_KEY_PROV_INFO*)malloc(cbData))
        printf("Memory has been allocated.\n");
    else
        HandleError("Malloc operation failed. ");

    //------------------------------------------------------------------------
    // Получение подробной информации о ключевом контейнере из расширенных свойств
    // контекста сертификата.
    if(CertGetCertificateContextProperty(pContext, dwPropId, pbData, &cbData))
    {
        printf("CertGetCertificateContextProperty was started for the 2-nd time\n");
        printf( "ContainerName is  %S ProvType = %d\n", pbData->pwszContainerName,
            pbData->dwProvType);
    }
    else
    {
        printf("CertGetCertificateContextProperty was started for the 2-nd time\n");
        HandleError("It's impossible to get the certificate property!\n ");
    }

    CComPtr<IXMLDSigKey> keyCSPRef;
    if (FAILED(xmldsig->createKeyFromCSP(pbData->dwProvType,
        pbData->pwszProvName, pbData->pwszContainerName, 0, &keyCSPRef))
        || !keyCSPRef)
    {
        printf("createKeyFromCSP failed.\n");
        return false;
    }

    //----------------------------------------------------
    // Создание ключа подписи по контексту сертификата.

    CComPtr<IXMLDSigKeyEx> keyRef;
    if (FAILED(xmldsig->createKeyFromCertContext((void*)pContext, &keyRef))
        || !keyRef)
    {
        printf("createKeyFromCertContext failed.\n");
        return false;
    }

    //----------------------------------------------------
    // Подпись XML-документа на полученном ключе.

    CComPtr<IXMLDSigKey> signKeyRef;
    if (FAILED(xmldsig->sign(keyRef, fwWriteKeyInfo, &signKeyRef))
        || !signKeyRef)
    {
        printf("sign failed.\n");
        return false;
    }

    printf("The specified data was signed successfully.\n");
    printf("Resultant signature:\n");

    //--------------------------------------------------------------------------
    // Освобождение контекста сертификата.
    if(pContext)
        CertFreeCertificateContext(pContext);

    //--------------------------------------------------------------------------
    // Закрытие хранилища сертификатов.

    if(CertCloseStore(hStore, 0))
    {
        printf("Store was closed successfully!\n");
        printf("\n");
    }
    else
    {
        printf("Attempt to close the store is failed\n");
        exit(1);
    }

    CComBSTR bstrXml;
    if (SUCCEEDED(xmldoc->get_xml(&bstrXml)))
    {
        printf("%S\n", bstrXml.m_str);
        // Запись подписи в файл outfile.
        if(FAILED(xmldoc->save(outfile))) {
            printf("can't save the signed signature to file: %S.\n", outfile.bstrVal);
            return false;
        }
        printf("signature saved to file: %S\n", outfile.bstrVal);
    }
    return true;
}// Конец описания SignXML

//-------------------------------------------------------------------------------
// Описание функции инициализации объектов.
//-------------------------------------------------------------------------------
bool initObjects(void)
{
    if(FAILED(xmldsig.CoCreateInstance(__uuidof(MXDigitalSignature50))))
    {
        printf("Installation of msxml5 is required to run this app.\n");
        return false;
    }
    if(FAILED(xmldoc.CoCreateInstance(__uuidof(DOMDocument50)))) {
        printf("Installation of msxml5 is required to run this app.\n");
        return false;
    }
    xmldoc->put_async(VARIANT_FALSE);
    xmldoc->put_validateOnParse(VARIANT_FALSE);
    xmldoc->put_preserveWhiteSpace(VARIANT_TRUE);
    xmldoc->put_resolveExternals(VARIANT_FALSE);
    return true;
}
// Конец описания initObjects

// Конец примера

    Требования:

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше. Необходим MSXML 5.0.


Пример проверки подписи XML-документа

Данный пример демонстрирует проверку подписи XML-документа, а также проверку цепочки сертификатов, начиная с сертификата, на котором осуществлялась подпись.

//--------------------------------------------------------------------
// Пример проверки подписи документа MSXML 5.0 на ключе, получаемом из
// DOM узла <ds:KeyInfo> подписанного XML-документа.
// Также данная программа осуществляет проверку действительности цепочки
// сертификатов, начиная с сертификата, на котором осуществлялась подпись,
// и заканчивая корневым сертификатом.
// В качестве обязательного аргумента командной строки выступает
// "out_signature.xml" - имя XML-документа, полученного во время подписи.
//
// НЕОБХОДИМО установить CAPICOM (http://www.microsoft.com/downloads/details.aspx?FamilyID=860ee43a-a843-462f-abb5-ff88ea5896f6&DisplayLang=en)
//--------------------------------------------------------------------

#include <locale.h>
#include <atlbase.h>
#include "msxml5.h"

// Для работы следующего #import-а CAPICOM должен быть зарегистрирован правильно.
// VS регистрирует его неправильно (с некоторых пор CAPICOM устанавливается VS),
// "неправильно" означает, что не только #import не будет работать,
// но и некоторые объекты будут работать с ошибками.
// Необходимо выполнить команду (важен полный путь к библиотеке):
// regsvr32 "H:\Program Files\Common Files\Microsoft Shared\CAPICOM\CapiCom.dll"
#import "libid:bd26b198-ee42-4725-9b23-afa912434229"
using namespace CAPICOM;

#define DSIGNS L"xmlns:ds='http://www.w3.org/2000/09/xmldsig#'"

//-------------------------------------------------------------
// Объявление и инициализация переменных.

CComPtr<IXMLDOMDocument2> xmldoc;
CComPtr<IXMLDigitalSignature> xmldsig;

bool initObjects(void);
bool LoadXML(VARIANT sigFile);
bool SetSignature(BSTR queryString);
bool VerifyXML(XMLDSIG_WRITEKEYINFO fwWriteKeyInfo, BSTR queryString);
bool CheckCertificateValidity(IXMLDSigKey *pKey);
void HandleError(char *s);

// Проверка подписи XML-документа.
int _tmain(int argc, TCHAR **argv)
{
    setlocale(LC_ALL, ".1251");
    // Инициализация COM библиотеки.
    if (FAILED(CoInitialize(NULL)))
        HandleError("can't initialize COM Lib");

    // Разбор командной строки.
    if(argc < 2)
        HandleError("usage: xmlverify test.xml");

    // Инициализация объектов.
    if(!initObjects())
        exit(-1);

    CComVariant sigFile(argv[1]);
    printf("Verifying %S\n\n", sigFile.bstrVal);
    if(!LoadXML(sigFile))
        exit(-1);

    if(!SetSignature(CComBSTR(L".//ds:Signature")))
        exit(-1);

    // Проверка подписи XML-документа.
    if(!VerifyXML(CERTIFICATES, L".//ds:KeyInfo/ds:X509Data"))
        exit(-1);
    //if(!VerifyXML(KEYVALUE, L".//ds:KeyInfo/ds:KeyValue"))
    //    exit(-1);

    return 0;
}

//---------------------------------------------------------------------------
// Описание функции загрузки XML-документа.
//---------------------------------------------------------------------------
bool LoadXML(VARIANT sigFile)
{
    VARIANT_BOOL isSuccessful = VARIANT_FALSE;
    if(FAILED(xmldoc->load(sigFile, &isSuccessful)) || isSuccessful == VARIANT_FALSE)
    {
        printf("Can't load %S\n", sigFile.bstrVal);
        return false;
    }
    if (FAILED(xmldoc->setProperty(L"SelectionNamespaces", CComVariant(DSIGNS))))
    {
        printf("setProperty failed\n");
        return false;
    }
    return true;
}// Конец описания функции LoadXML

//------------------------------------------------------------------------------
// Определение свойств подписи в соответствии с DOM узлом <ds:Signature>
// XML-документа.

bool SetSignature(BSTR queryString)
{
    CComPtr<IXMLDOMNode> signatureNode;
    if (FAILED(xmldoc->selectSingleNode(queryString, &signatureNode)))
    {
        printf("Failed to get Signature node.\n");
        return false;
    }
    if (FAILED(xmldsig->putref_signature(signatureNode)))
    {
        printf("Failed to set the signature property.\n");
        return false;
    }
    signatureNode.Release();
    // Попробуем тут же получить обратно и проверить
    if(FAILED(xmldsig->get_signature(&signatureNode)) || !signatureNode)
    {
        printf("Invalid signature template\n");
        return false;
    }
    return true;
}

// Описание функции проверки подписи XML-документа.
bool VerifyXML(XMLDSIG_WRITEKEYINFO fwWriteKeyInfo, BSTR queryString)
{
    // Проверка DOM узла <ds:KeyInfo> XML-документа.
    CComPtr<IXMLDOMNode> pKeyInfo;
    if (FAILED(xmldoc->selectSingleNode(queryString, &pKeyInfo)) || !pKeyInfo)
    {
        printf("Invalid <ds:KeyInfo>\n");
        return false;
    }

    CComPtr<IXMLDSigKey> pKey;
    if(FAILED(xmldsig->createKeyFromNode(pKeyInfo, &pKey)) || !pKey)
    {
        printf("Invalid key from <ds:KeyInfo>\n");
        return false;
    }

   // Получение ключа проверки цепочки сертификатов и проверка подписи.
    CComPtr<IXMLDSigKey> pKeyOut;
    if(FAILED(xmldsig->verify(pKey, &pKeyOut)) || !pKeyOut) {
        printf("Invalid signature.\n");
        return false;
    }

    printf("\n");
    printf("Signature verified on the data.\n\n");

    // Проверка цепочки сертификатов, начиная с сертификата, на котором осуществлялась подпись.
   if (fwWriteKeyInfo & CERTIFICATES)
      return CheckCertificateValidity(pKeyOut);
   return true;
}

//-------------------------------------------------------------------------------
// Описание функции инициализации объектов.
//-------------------------------------------------------------------------------
bool initObjects(void)
{
    if(FAILED(xmldsig.CoCreateInstance(__uuidof(MXDigitalSignature50))))
    {
        printf("Installation of msxml5 is required to run this app.\n");
        return false;
    }
    if(FAILED(xmldoc.CoCreateInstance(__uuidof(DOMDocument50)))) {
        printf("Installation of msxml5 is required to run this app.\n");
        return false;
    }
    xmldoc->put_async(VARIANT_FALSE);
    xmldoc->put_validateOnParse(VARIANT_FALSE);
    xmldoc->put_preserveWhiteSpace(VARIANT_TRUE);
    xmldoc->put_resolveExternals(VARIANT_FALSE);
    return true;
}
// Конец описания initObjects

//---------------------------------------------------------------------------
// Описание функции проверки цепочки сертификатов, начиная с сертификата, на
// котором осуществлялась подпись XML-документа.
//---------------------------------------------------------------------------
bool CheckCertificateValidity(IXMLDSigKey *pKey)
{
    if(pKey == NULL)
    {
        printf("invalid key object.\n");
        return false;
    }

    // Получение сертификата, на котором осуществлялась подпись, из ключа проверки.
    CComPtr<IUnknown> certUnk;
    if(FAILED(pKey->getVerifyingCertificate(&certUnk)))
    {
        printf("Can't get verifying certificate\n");
        return false;
    }

    ICertificatePtr pCert(certUnk.Detach());

    //-----------------------------------------------------------------------
    // Построение и прохождение по доверенной цепочке сертификатов.

    IChain2Ptr pChain = NULL;
    HRESULT hr = pChain.CreateInstance(__uuidof(Chain));
    if(FAILED(hr))
    {
        printf("Can't instantiate a trust chain.\n");
        return false;
    }

    if(VARIANT_FALSE == pChain->Build(pCert))
    {
        printf("broken trust chain.\n");
        return false;
    }

    printf("Examining certificate chain:\n");
    long count = pChain->Certificates->Count;
    for(long i=1; i<=count; i++)
    {
        printf("  Certificate No. %d:\n", i);
        if(pCert)
        {
            pCert.Release();
            pCert=NULL;
        }
        pCert = pChain->Certificates->Item[i];
        if(pCert == NULL)
        {
            printf("Can't get the %d-th certificate.\n", i);
            return false;
        }
        printf("     subject: %S\n", (LPWSTR)pCert->SubjectName);
        printf("     issuer:  %S\n\n", (LPWSTR)pCert->IssuerName);
    }

    //-----------------------------------------------------------------------
    // Проверка корневого сертификата в цепочке.

    if(pCert)
    {
        pCert.Release();
        pCert=NULL;
    }

    pCert = pChain->Certificates->Item[count];
    if(pCert == NULL)
    {
        printf("Can't get root certificate.\n");
        return false;
    }
    printf("Display the Root certificate:\n");
    printf("   subject:  %S\n", (LPWSTR)pCert->SubjectName);
    printf("   issuer:   %S\n\n", (LPWSTR)pCert->IssuerName);

    if(pCert)
        pCert.Release();
    if(pChain)
        pChain.Release();
    printf("Certificate used is valid.\n");
    return true;
}
// Конец описания CheckCertificateValidity

// Конец примера

Требования:

Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше. Необходим MSXML 5.0.


Пример создания и проверки двух подписей XML-документа

В данном примере осуществляется создание и проверка двух независимых подписей XML-документа, а также осуществляется проверка цепочки сертификатов, начиная с сертификата, на котором осуществлялась подпись. Этот пример демонстрирует использование следующих функций
  • CertOpenStore в MS CryptoAPI 2.0 World Wide Web link
  • CertFindCertificateInStore в MS CryptoAPI 2.0 World Wide Web link
  • CertGetCertificateContextProperty в MS CryptoAPI 2.0 World Wide Web link
  • CertFreeCertificateContext в MS CryptoAPI 2.0 World Wide Web link
  • CertCloseStore в MS CryptoAPI 2.0 World Wide Web link

//--------------------------------------------------------------------
// Пример создания и проверки двух независимых подписей документа MSXML 5.0.
// Ключ подписи получается по имени ключевого контейнера. Имя контейнера, в свою очередь,
// получается из расширенных свойств заданного сертификата.
// Ключ проверки подписи получается из DOM узла <ds:KeyInfo> подписанного XML-документа.
// Данная программа имеет 3 аргумента командной строки:
// 1) Имя исходного XML-документа (документ должен соответствовать
// шаблону, приведенному в примере).
// 2) Имя сертификата для первой подписи.
// 3) Имя сертификата для второй подписи.
//
// К примеру прилагаются два шаблона:
// doc_to_sign_two.xml шаблон для подписи всего документа
// node_to_sign_two.xml шаблон для подписи одного элемента <ElementToSign...>
//
// В состав примеров входят два документа полученные из шаблонов InfoPath
// примера XMLSignForVerify: (ip_doc_signed2.xml, ip_node_signed2.xml).
// Эти документы могут быть использованы как вход к примеру для проверки
// подписи под документами InfoPath. Для проверки подписи под этими
// длкументами необходимо, закоментаривать кода примера связанный с
// простановкой подписей.
//
// НЕОБХОДИМО установить CAPICOM (http://www.microsoft.com/downloads/details.aspx?FamilyID=860ee43a-a843-462f-abb5-ff88ea5896f6&DisplayLang=en)
//--------------------------------------------------------------------

#include <locale.h>
#include <atlbase.h>
#include "msxml5.h"

// Для работы следующего #import-а CAPICOM должен быть зарегистрирован правильно.
// VS регистрирует его неправильно (с некоторых пор CAPICOM устанавливается VS),
// "неправильно" означает, что не только #import не будет работать,
// но и некоторые объекты будут работать с ошибками.
// Необходимо выполнить команду (важен полный путь к библиотеке):
// regsvr32 "H:\Program Files\Common Files\Microsoft Shared\CAPICOM\CapiCom.dll"
#import "libid:bd26b198-ee42-4725-9b23-afa912434229"
using namespace CAPICOM;

#define DSIGNS L"xmlns:ds='http://www.w3.org/2000/09/xmldsig#'"
#define OUTFILE L"out_signatures.xml"

//-------------------------------------------------------------
// Объявление и инициализация переменных.

CComPtr<IXMLDOMDocument2> xmldoc;
CComPtr<IXMLDigitalSignature> xmldsig;

bool initObjects(void);
bool LoadXML(VARIANT sigFile);
bool SetSignature(BSTR queryString);
bool SignXML(XMLDSIG_WRITEKEYINFO fwWriteKeyInfo, TCHAR* userName,
    VARIANT outfile);
bool VerifyXML(XMLDSIG_WRITEKEYINFO fwWriteKeyInfo, BSTR queryString);
bool CheckCertificateValidity(IXMLDSigKey *pKey);
void HandleError(char *s);

//---------------------------------------------------------------------------
// Создание и проверка двух независимых подписей XML-документа.
//---------------------------------------------------------------------------
int _tmain(int argc, TCHAR **argv)
{
    setlocale(LC_ALL, ".1251");
    // Инициализация COM библиотеки.
    if (FAILED(CoInitialize(NULL)))
        HandleError("can't initialize COM Lib");

    // Разбор командной строки.
    if(argc < 4)
        HandleError("usage: XMLSignForVerify test.xml certname1 certname2\n");

    //-----------------------------------------------------------------------
    // Инициализация объектов.
    if(!initObjects())
        exit(-1);

    CComVariant sigFile(argv[1]);  //имя исходного xml-документа для подписи
    printf("Signing %S\n\n", sigFile.bstrVal);

    //------------------------------------------------------------------------------
    // Создание двух независимых подписей XML-документа.

    if(!LoadXML(sigFile))
        exit(-1);
    if (!SetSignature(CComBSTR(L".//ds:Signature[@Id='FirstSignature']")))
        exit(-1);
    CComVariant outfile(OUTFILE);
    if (!SignXML(CERTIFICATES, CComBSTR(argv[2]), outfile))
        exit(-1);

    printf("\n");

    if (!SetSignature(CComBSTR(L".//ds:Signature[@Id='SecondSignature']")))
        exit(-1);
    if (!SignXML(CERTIFICATES, CComBSTR(argv[3]), outfile))
        exit(-1);

    //------------------------------------------------------------------------------
    // Проверка двух независимых подписей XML-документа.

    if (!LoadXML(outfile))
        exit(-1);
    if (!SetSignature(CComBSTR(L".//ds:Signature[@Id='FirstSignature']")))
        exit(-1);
    if (!VerifyXML(CERTIFICATES, CComBSTR(L".//ds:Signature[@Id='FirstSignature']"
        L"/ds:KeyInfo/ds:X509Data")))
    {
        exit(-1);
    }

    printf("\n");

    if (!SetSignature(CComBSTR(L".//ds:Signature[@Id='SecondSignature']")))
        exit(-1);
    if (!VerifyXML(CERTIFICATES, CComBSTR(L".//ds:Signature[@Id='SecondSignature']"
        L"/ds:KeyInfo/ds:X509Data")))
    {
        exit(-1);
    }

    return 0;
}

//---------------------------------------------------------------------------
// Описание функции загрузки XML-документа.
//---------------------------------------------------------------------------
bool LoadXML(VARIANT sigFile)
{
    VARIANT_BOOL isSuccessful = VARIANT_FALSE;
    if(FAILED(xmldoc->load(sigFile, &isSuccessful)) || isSuccessful == VARIANT_FALSE)
    {
        printf("Can't load %S\n", sigFile.bstrVal);
        return false;
    }
    if (FAILED(xmldoc->setProperty(L"SelectionNamespaces", CComVariant(DSIGNS))))
    {
        printf("setProperty failed\n");
        return false;
    }
    return true;
}// Конец описания функции LoadXML

//------------------------------------------------------------------------------
// Определение свойств подписи в соответствии с DOM узлом <ds:Signature>
// XML-документа.

bool SetSignature(BSTR queryString)
{
    CComPtr<IXMLDOMNode> signatureNode;
    if (FAILED(xmldoc->selectSingleNode(queryString, &signatureNode)))
    {
        printf("Failed to get Signature node.\n");
        return false;
    }
    if (FAILED(xmldsig->putref_signature(signatureNode)))
    {
        printf("Failed to set the signature property.\n");
        return false;
    }
    signatureNode.Release();
    // Попробуем тут же получить обратно и проверить
    if(FAILED(xmldsig->get_signature(&signatureNode)) || !signatureNode)
    {
        printf("Invalid signature template\n");
        return false;
    }
    return true;
}

//---------------------------------------------------------------------------
// Описание функции подписи XML-документа.
//---------------------------------------------------------------------------

bool SignXML(XMLDSIG_WRITEKEYINFO fwWriteKeyInfo,
    TCHAR* userName, VARIANT outfile)
{
    if (fwWriteKeyInfo & CERTIFICATES)
        printf("Sign with fwWriteKeyInfo = CERTIFICATES:\n");

    HCERTSTORE hStore = NULL; // Дескритор хранилища сертификатов
    //------------------------------------------------------------------------------
    // Открытие хранилища сертификатов "MY" текущего пользователя.
    hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0,
        CERT_STORE_OPEN_EXISTING_FLAG |CERT_STORE_READONLY_FLAG |
        CERT_SYSTEM_STORE_CURRENT_USER, L"MY");
    if(!hStore)
    {
        HandleError("The store could not be opened!\n");
    }
    else
    {
        printf("The store is open!\n");
    }

    //-----------------------------------------------------------------------
    // Получение сертификата с заданным именем из хранилища сертификатов.
    PCCERT_CONTEXT pContext = NULL;
    pContext = CertFindCertificateInStore(hStore,
        X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR_W,
        userName, NULL);
    if(pContext == NULL)
    {
        HandleError("There is no such a certificate in the store\n");
    }

    // Параметр для получения информации из свойств сертификата
    DWORD dwPropId = CERT_KEY_PROV_INFO_PROP_ID;
    DWORD cbData; // Длина буфера данных

    //-----------------------------------------------------------------------
    // Получение информации из расширенных свойств контекста сертификата. Определение размера
    // возвращаемых данных.

    if(CertGetCertificateContextProperty(pContext, dwPropId, NULL, &cbData))
    {
        printf("CertGetCertificateContextProperty was started for the 1-st time\n");
    }
    else
    {
        printf("CertGetCertificateContextProperty was started for the 1-st time\n");
        HandleError("It's impossible to get the certificate property!\n ");
    }

    //-----------------------------------------------------------------------
    // Указатель на структуру CRYPT_KEY_PROV_INFO, содержащую подробную информацию
    // о ключевом контейнере.
    CRYPT_KEY_PROV_INFO *pbData;

    //-----------------------------------------------------------------------
    // Выделение памяти.

    pbData = (CRYPT_KEY_PROV_INFO*)malloc(cbData);
    if(pbData)
        printf("Memory has been allocated.\n");
    else
        HandleError("Malloc operation failed. ");

    //-----------------------------------------------------------------------
    // Получение подробной информации о ключевом контейнере из расширенных свойств
    // контекста сертификата.

    if(CertGetCertificateContextProperty(pContext, dwPropId, pbData, &cbData))
    {
        printf("CertGetCertificateContextProperty was started for the 2-nd time\n");
        printf( "ContainerName is  %S\n", pbData->pwszContainerName);
    }
    else
    {
        printf("CertGetCertificateContextProperty was started for the 2-nd time\n");
        HandleError("It's impossible to get the certificate property!\n ");
    }

    //--------------------------------------------------------------------------
    // Освобождение контекста сертификата.

    if(pContext)
        CertFreeCertificateContext(pContext);

    //--------------------------------------------------------------------------
    // Закрытие хранилища сертификатов.

    if(CertCloseStore(hStore, 0))
    {
        printf("Store was closed successfully!\n");
        printf("\n");
    }
    else
    {
        printf("Attempt to close the store is failed\n");
        exit(1);
    }

    //-----------------------------------------------------------------------
    // Создание ключа подписи по полученному имени ключевого контейнера.

    CComPtr<IXMLDSigKey> keyRef;
    if (FAILED(xmldsig->createKeyFromCSP(pbData->dwProvType,
        pbData->pwszProvName, pbData->pwszContainerName, 0, &keyRef))
        || !keyRef)
    {
        printf("createKeyFromCSP key\n");
        return false;
    }

    //-----------------------------------------------------------------------
    // Подпись XML-документа на полученном ключе.

    CComPtr<IXMLDSigKey> signKeyRef;
    if (FAILED(xmldsig->sign(keyRef, fwWriteKeyInfo, &signKeyRef))
        || !signKeyRef)
    {
        printf("sign failed.\n");
        return false;
    }
    printf("The specified data was signed successfully.\n");
    printf("Resultant signature:\n");

    CComBSTR bstrXml;
    if (SUCCEEDED(xmldoc->get_xml(&bstrXml)))
    {
        printf("%S\n", bstrXml.m_str);
        // Запись подписи в файл outfile.
        if(FAILED(xmldoc->save(outfile))) {
            printf("can't save the signed signature to file: %S.\n", outfile.bstrVal);
            return false;
        }
        printf("signature saved to file: %S\n", outfile.bstrVal);
    }
    return true;
}
// Конец описания SignXML

//---------------------------------------------------------------------------
// Описание функции проверки подписи XML-документа.
//---------------------------------------------------------------------------

bool VerifyXML(XMLDSIG_WRITEKEYINFO fwWriteKeyInfo, BSTR queryString)
{
    if (fwWriteKeyInfo & CERTIFICATES)
        printf("Verify with fwWriteKeyInfo = CERTIFICATES:\n");

    // Проверка DOM узла <ds:KeyInfo> XML-документа.
    CComPtr<IXMLDOMNode> pKeyInfo;
    if (FAILED(xmldoc->selectSingleNode(queryString, &pKeyInfo)) || !pKeyInfo)
    {
        printf("Invalid <ds:KeyInfo>\n");
        return false;
    }

    // Получение ключа проверки подписи из DOM узла <ds:KeyInfo> XML-документа.
    CComPtr<IXMLDSigKey> pKey;
    if(FAILED(xmldsig->createKeyFromNode(pKeyInfo, &pKey)) || !pKey)
    {
        printf("Invalid key from <ds:KeyInfo>\n");
        return false;
    }

    //-----------------------------------------------------------------------
    // Получение ключа проверки цепочки сертификатов и проверка подписи.

    CComPtr<IXMLDSigKey> pKeyOut;
    if(FAILED(xmldsig->verify(pKey, &pKeyOut)) || !pKeyOut) {
        printf("Invalid signature.\n");
        return false;
    }

    printf("\n");
    printf("Signature verified on the data.\n\n");

    // Проверка цепочки сертификатов, начиная с сертификата, на котором осуществлялась подпись.
    if(fwWriteKeyInfo & CERTIFICATES)
        return CheckCertificateValidity(pKeyOut);
    return true;
}
// Конец описания VerifyXML

//-------------------------------------------------------------------------------
// Описание функции инициализации объектов.
//-------------------------------------------------------------------------------
bool initObjects(void)
{
    if(FAILED(xmldsig.CoCreateInstance(__uuidof(MXDigitalSignature50))))
    {
        printf("Installation of msxml5 is required to run this app.\n");
        return false;
    }
    if(FAILED(xmldoc.CoCreateInstance(__uuidof(DOMDocument50)))) {
        printf("Installation of msxml5 is required to run this app.\n");
        return false;
    }
    xmldoc->put_async(VARIANT_FALSE);
    xmldoc->put_validateOnParse(VARIANT_FALSE);
    xmldoc->put_preserveWhiteSpace(VARIANT_TRUE);
    xmldoc->put_resolveExternals(VARIANT_FALSE);
    return true;
}
// Конец описания initObjects

//---------------------------------------------------------------------------
// Описание функции проверки цепочки сертификатов, начиная с сертификата, на
// котором осуществлялась подпись XML-документа.
//---------------------------------------------------------------------------
bool CheckCertificateValidity(IXMLDSigKey *pKey)
{
    if(pKey == NULL)
    {
        printf("invalid key object.\n");
        return false;
    }

    // Получение сертификата, на котором осуществлялась подпись, из ключа проверки.
    CComPtr<IUnknown> certUnk;
    if(FAILED(pKey->getVerifyingCertificate(&certUnk)))
    {
        printf("Can't get verifying certificate\n");
        return false;
    }

    ICertificatePtr pCert(certUnk.Detach());

    //-----------------------------------------------------------------------
    // Построение и прохождение по доверенной цепочке сертификатов.

    IChain2Ptr pChain = NULL;
    HRESULT hr = pChain.CreateInstance(__uuidof(Chain));
    if(FAILED(hr))
    {
        printf("Can't instantiate a trust chain.\n");
        return false;
    }

    if(VARIANT_FALSE == pChain->Build(pCert))
    {
        printf("broken trust chain.\n");
        return false;
    }

    printf("Examining certificate chain:\n");
    long count = pChain->Certificates->Count;
    for(long i=1; i<=count; i++)
    {
        printf("  Certificate No. %d:\n", i);
        if(pCert)
        {
            pCert.Release();
            pCert=NULL;
        }
        pCert = pChain->Certificates->Item[i];
        if(pCert == NULL)
        {
            printf("Can't get the %d-th certificate.\n", i);
            return false;
        }
        printf("     subject: %S\n", (LPWSTR)pCert->SubjectName);
        printf("     issuer:  %S\n\n", (LPWSTR)pCert->IssuerName);
    }

    //-----------------------------------------------------------------------
    // Проверка корневого сертификата в цепочке.

    if(pCert)
    {
        pCert.Release();
        pCert=NULL;
    }

    pCert = pChain->Certificates->Item[count];
    if(pCert == NULL)
    {
        printf("Can't get root certificate.\n");
        return false;
    }
    printf("Display the Root certificate:\n");
    printf("   subject:  %S\n", (LPWSTR)pCert->SubjectName);
    printf("   issuer:   %S\n\n", (LPWSTR)pCert->IssuerName);

    if(pCert)
        pCert.Release();
    if(pChain)
        pChain.Release();
    printf("Certificate used is valid.\n");
    return true;
}
// Конец описания CheckCertificateValidity

// Конец примера

    Требования:

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше. Необходим MSXML 5.0.


Примеры использования криптопровайдера совместно с функциями CAPICOM.

В данном разделе приводятся примеры, демонстрирующие использование функций CAPICOM для реализации операций с криптопровайдером.

  • Пример подписи и проверки подписи при помощи CAPICOM
  • Пример зашифрования и расшифрования при помощи CAPICOM


Пример подписи и проверки подписи при помощи CAPICOM

Данный пример демонстрирует осуществление подписи и проверки подписи текстового документа при помощи инструментария CAPICOM.

'------------------------------------------------------------------------------
' В данном script-примере осуществляется подпись и проверка подписи
' содержимого файла при помощи инструментария CAPICOM.
'------------------------------------------------------------------------------

Option Explicit

Const ForReading = 1, ForWriting = 2

' Команды.
Const Unknown                                               = 0
Const Sign                                                  = 1
Const CoSign                                                = 2
Const Verify                                                = 3

' CAPICOM константы.
Const CAPICOM_CURRENT_USER_STORE                            = 2

Const CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY            = 6
Const CAPICOM_CERTIFICATE_FIND_TIME_VALID                   = 9

Const CAPICOM_VERIFY_SIGNATURE_ONLY                         = 0

Const CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT         = 0

Const CAPICOM_PROPID_KEY_PROV_INFO                          = 2

' Аргументы командной строки.
Dim Command          : Command                              = Unknown
Dim StoreLocation    : StoreLocation                        = Null
Dim VerifyFlag       : VerifyFlag                           = CAPICOM_VERIFY_SIGNATURE_ONLY
Dim IncludeOption    : IncludeOption                        = CAPICOM_CERTIFICATE_INCLUDE_CHAIN_EXCEPT_ROOT
Dim bDetached        : bDetached                            = False

' Фильтр.
Dim FileNames()

' В первую очередь осуществляется проверка того, что script выполняется при помощи CScript.exe.
If InStr(1, UCase(Wscript.FullName), "CSCRIPT.EXE", vbTextCompare) = 0 Then
   Wscript.Echo "This script can only be executed by CScript.exe." & vbCRLF & vbCRLF &_
                "You can either:" & vbCRLF & vbCRLF & _
                "1. Set CScript.exe as the default (Run CScript //h:cscript), or" & vbCRLF & _
                "2. Run CScript.exe directly as in, CScript " & Wscript.ScriptName & "."
   Wscript.Quit(-1)
End If

' Разбор командной сроки.
ParseCommandLine

' Поиск сертификата, на котором будет осуществляться операция подписи.
Dim Signer
Set Signer = CreateObject("CAPICOM.Signer")

' Определение свойств операции подписи.
If Command = Sign OR Command = CoSign Then
      Dim iIndex
      Dim Store
      Dim Certificates
      Dim StoreName : StoreName = "MY"

      ' Открытие соответствующего хранилища.
      Set Store = CreateObject("CAPICOM.Store")

      StoreLocation = CAPICOM_CURRENT_USER_STORE

      Store.Open StoreLocation, StoreName

      ' В качестве кандитатов на сертификат, на котором будет осуществлена подпись,
      ' изначально определяются все сертификаты хранилища.
      Set Certificates = Store.Certificates

      ' Из них не рассматриваются сертификаты, в которых отсутствует закрытый ключ.
      If Certificates.Count > 0 Then
         Set Certificates = Certificates.Find(CAPICOM_CERTIFICATE_FIND_EXTENDED_PROPERTY, _
         CAPICOM_PROPID_KEY_PROV_INFO)
      End If

      ' Из них выбираются только сертификаты, действительные в настоящее время.
      If Certificates.Count > 0 Then
         Set Certificates = Certificates.Find(CAPICOM_CERTIFICATE_FIND_TIME_VALID, Now)
      End If

      ' Выбор сертификата для подписи. Если после проведенной фильтрации осталось несколько кандидатов,
      ' то пользователю предоставляется выбор одного из них (при помощи диалогового окна).
      Select Case Certificates.Count
      Case 0
         Wscript.Stdout.Writeline "Error: No signing certificate can be found."
         Wscript.Quit(1)

      Case 1
         Signer.Certificate = Certificates(1)

      Case Else
         Set Certificates = Certificates.Select("CSignData.vbs", "Please select a certificate to sign " _
         & FileNames(0) & ".")
         If Certificates.Count = 0 Then
            Wscript.Stdout.Writeline "Error: Certificate selection dialog was cancelled."
            Wscript.Quit(2)
         End If
         Signer.Certificate = Certificates(1)

      End Select

      Set Certificates = Nothing
      Set Store = Nothing

   Signer.Options = IncludeOption

   End If

' Выполнение требуемой операции.
Select Case Command
Case Sign
   DoSignCommand FileNames, bDetached, Signer

Case CoSign
   DoCoSignCommand FileNames, bDetached, Signer

Case Verify
   DoVerifyCommand FileNames, bDetached, VerifyFlag

End Select

' Освобождение ресурсов.
Set Signer = Nothing

Wscript.Quit(0)

' Конец main

'------------------------------------------------------------------------------
' Функиция DoSignCommand  подписывает содержимое файла FileNames(0)
' и записывает подписанные данные в FileNames(1).
'------------------------------------------------------------------------------

Sub DoSignCommand (FileNames, bDetached, Signer)
   Dim Content
   Dim Message
   Dim SignedData

   ' Создание объекта SignedData.
   Set SignedData = CreateObject("CAPICOM.SignedData")

   ' Распечатка информативного сообщения.
   Wscript.Stdout.Writeline "Signing text file " & FileNames(0) & "."
   Wscript.Stdout.Writeline

   ' Загрузка содержимого файла для подписи.
   LoadFile FileNames(0), Content

   ' Подпись.
   SignedData.Content = Content
   Message = SignedData.Sign(Signer, bDetached)

   ' Сохранение подписанных данных в FileNames(1).
   SaveFile FileNames(1), Message
   Wscript.Stdout.Writeline "Successful - Signed message saved to " & FileNames(1) & "."

   ' Освобождение ресурсов.
   Set SignedData = Nothing

End Sub 'Конец DoSignCommand

'------------------------------------------------------------------------------
' Функция DoCoSignCommand подписывает текстовый файл FileNames(0)и сохраняет
' заново подписанное содержимое в FileNames(1).
'------------------------------------------------------------------------------

Sub DoCoSignCommand (FileNames, bDetached, Signer)
   Dim Content
   Dim Message
   Dim SignedData

   ' Создание объекта SignedData.
   Set SignedData = CreateObject("CAPICOM.SignedData")

   ' Распечатка информативного сообщения.
   Wscript.Stdout.Writeline "CoSigning text file " & FileNames(0) & "."
   Wscript.Stdout.Writeline

   ' Загрузка подписанных данных.
   LoadFile FileNames(0), Message

   ' Обработка отделенных данных
   If True = bDetached Then
      LoadFile FileNames(1), Content
      SignedData.Content = Content
      Wscript.Stdout.Writeline "content file " & FileNames(1) & "."
   End If

   ' Проверка подписанных данных.
   SignedData.Verify Message, bDetached, VerifyFlag

   ' Повторная подпись.
   Message = SignedData.CoSign(Signer, bDetached)

   ' Сохранение внось подписанных данных в FileNames(0).
   SaveFile FileNames(0), Message
   Wscript.Stdout.Writeline "Successful - CoSigned message saved to " & FileNames(0) & "."

   ' Освобождение ресурсов.
   Set SignedData = Nothing

End Sub ' Конец DoCoSignCommand

'------------------------------------------------------------------------------
' Функция DoVerifyCommand проверяется подписанный текстовый файл.
'------------------------------------------------------------------------------

Sub DoVerifyCommand (FileNames, bDetached, VerifyFlag)
   Dim Content
   Dim Message
   Dim SignedData

   ' Создание объекта SignedData.
   Set SignedData = CreateObject("CAPICOM.SignedData")

   ' Распечатка информативного сообщения.
   Wscript.Stdout.Writeline "Verifying signed text file " & FileNames(0) & ", please wait..."
   Wscript.Stdout.Writeline

   ' Загрузка подписанных данных для проверки.
   LoadFile FileNames(0), Message

   ' Обработка отделенных данных
   If True = bDetached Then
   LoadFile FileNames(1), Content
   SignedData.Content = Content
   End If

   ' Проверка подписи.
   SignedData.Verify Message, bDetached, VerifyFlag

   ' Сохранение проверенного содержимого в FileNames(1).
   If False = bDetached Then
      SaveFile FileNames(1), SignedData.Content
      Wscript.Stdout.Writeline "Successful - Verified content saved to " & FileNames(1) & "."
   Else
      Wscript.Stdout.Writeline "Successful."
   End If

   ' Освобождение ресурсов.
   Set SignedData = Nothing

End Sub ' Конец DoVerifyCommand

'------------------------------------------------------------------------------
'Функция LoadFile читает содержимое текстового файла.
'------------------------------------------------------------------------------

Sub LoadFile (FileName, Buffer)
    Dim fso
    Set fso = CreateObject("Scripting.FileSystemObject")

    If Not fso.FileExists(FileName) Then
        Wscript.Stdout.Writeline "Error: File " & FileName & " not found."
        Wscript.Quit(-5)
    End If

    Dim ts
    Set ts = fso.OpenTextFile(FileName, ForReading)
    Buffer = ts.ReadAll

End Sub ' Конец LoadFile

'------------------------------------------------------------------------------
' Функция SaveFile сохраняет строку в файл.
'------------------------------------------------------------------------------

Sub SaveFile (FileName, Buffer)
    Dim fso
    Set fso = CreateObject("Scripting.FileSystemObject")

    Dim ts
    Set ts = fso.OpenTextFile(FileName, ForWriting, True)
    ts.Write Buffer

End Sub ' Конец SaveFile

'------------------------------------------------------------------------------
' Функция ParseCommandLine разбирает командную строку и устанавливает
' опции согласно ей.
'------------------------------------------------------------------------------

Sub ParseCommandLine

   ' Константы для разбора состояний, задаваемых командной строкой.
   Const ARG_STATE_COMMAND                   = 0
   Const ARG_STATE_OPTIONS                   = 1
   Const ARG_STATE_FILENAME                  = 13

   ' Разбор командной строки.
   Dim Arg
   Dim ArgState : ArgState = ARG_STATE_COMMAND

   For Each Arg In Wscript.Arguments
      Select Case ArgState
      Case ARG_STATE_COMMAND
         Select Case UCase(Arg)
         Case "SIGN"
            Command = Sign

         Case "COSIGN"
            Command = CoSign

         Case "VERIFY"
            Command = Verify

         Case Else
            DisplayUsage

         End Select

         ArgState = ARG_STATE_OPTIONS

      Case ARG_STATE_OPTIONS
         Select Case UCase(Arg)
         Case "-?", "/?"
            DisplayUsage

         Case Else
            If Left(Arg, 1) = "-"  OR Left(Arg, 1) = "/" Then
               DisplayUsage
            Else
               ReDim FileNames(0)
               FileNames(0) = Arg
            End If
            ArgState = ARG_STATE_FILENAME

         End Select

      Case ARG_STATE_FILENAME
         If Left(Arg, 1) = "-"  OR Left(Arg, 1) = "/" Then
            DisplayUsage
         Else
            ReDim Preserve FileNames(UBound(FileNames) + 1)
         End If
         FileNames(UBound(FileNames)) = Arg

      Case Else
         Wscript.Stdout.Writeline "Internal script error: Unknown argument state (" _
         & CStr(ArgState) & ") encountered."
         Wscript.Quit(-3)

      End Select
   Next

   ' Проверка правильности состояния.
   If ArgState <> ARG_STATE_FILENAME Then
      DisplayUsage
   End If

   ' Проверка опций.
   Select Case Command
   Case Sign
      ' Функция подписи должна иметь входной и выходной файлы.
      If (UBound(FileNames) - LBound(FileNames) + 1) <> 2 Then
         DisplayUsage
      End If

   Case Verify
      ' Функция проверки подписи должна иметь входной и выходной файлы.
      If (UBound(FileNames) - LBound(FileNames) + 1) <> 2 Then
         DisplayUsage
      End If

   End Select

End Sub ' Конец ParseCommandLine

'------------------------------------------------------------------------------
' Функция DisplayUsage распечатывает информацию об использовании данного
' примера, и затем осуществляет выход с ошибкой.
'------------------------------------------------------------------------------

Sub DisplayUsage

   Select Case Command
      Case Unknown
         Wscript.Stdout.Writeline "Usage: CSignData Command File1 [File2]"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "Command:"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "  Sign                   -- Sign a text file"
         Wscript.Stdout.Writeline "  CoSign                 -- CoSign a signed text file"
         Wscript.Stdout.Writeline "  Verify                 -- Verify a signed text file"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "For help on a specific command, enter ""CSignData Command -?"""

      Case Sign
         Wscript.Stdout.Writeline "Usage: CSignData Sign ContentFile SignedFile"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "The Sign command is used to sign a text file. Signing protects a file from"
         Wscript.Stdout.Writeline "tampering, and allows user to verify the signer based on signing certificate."
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "For non-detached signing, both the content and signature will be saved to"
         Wscript.Stdout.Writeline "SignedFile. For detached signing, only the signature is saved to SignedFile."
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "Parameters:"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "  -?                     -- This help screen"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "  ContentFile            -- Text file to be signed"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "  SignedFile             -- Signed file (contains signature only if detached)"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "Note: All non-fatal invalid options for this specific command will be ignored,"
         Wscript.Stdout.Writeline "      and the ** symbol indicates option can be listed multiple times."
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "      If there is only one certificate found in the MY store or PFX that"
         Wscript.Stdout.Writeline "      matches the requirement, that particular certificate will be used."
         Wscript.Stdout.Writeline "      However, if there is more than one certificate matching the requirement,"
         Wscript.Stdout.Writeline "      a dialog will be displayed to allow selection of the signing certificate."
         Wscript.Stdout.Writeline

      Case CoSign
         Wscript.Stdout.Writeline "Usage: CSignData CoSign SignedFile [ContentFile]"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "The CoSign command is used to cosign a signed text file. CoSigning provides the"
         Wscript.Stdout.Writeline "same type of benefits as signing, with an additional signature."
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "For non-detached cosigning, both the content and signatures will be saved to"
         Wscript.Stdout.Writeline "SignedFile. For detached cosigning, only the signatures are saved to"
         Wscript.Stdout.Writeline "SignedFile."
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "Parameters:"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "  -?                     -- This help screen"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "  SignedFile             -- Signed file (contains signature only if detached)"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "  ContentFile            -- Text file (required if detached)"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "Note: All non-fatal invalid options for this specific command will be ignored,"
         Wscript.Stdout.Writeline "      and the ** symbol indicates option can be listed multiple times."
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "      If there is only one certificate found in the MY store or PFX that"
         Wscript.Stdout.Writeline "      matches the requirement, that particular certificate will be used."
         Wscript.Stdout.Writeline "      However, if there is more than one certificate matching the requirement,"
         Wscript.Stdout.Writeline "      a dialog will be displayed to allow selection of the signing certificate."
         Wscript.Stdout.Writeline

       Case Verify
         Wscript.Stdout.Writeline "Usage: CSignData Verify SignedFile ContentFile"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "The Verify command is used to verify signed text file. Verification checks"
         Wscript.Stdout.Writeline "integrity of the signed file and determines if the signing certificate is"
         Wscript.Stdout.Writeline "valid and issued by a trusted party."
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "For non-detached signed file, the content will be extracted and saved to"
         Wscript.Stdout.Writeline "ContentFile. For detached signed file, the ContentFile is not modified."
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "Parameters:"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "  -?                     -- This help screen"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "  SignedFile             -- Signed file (contains signature only if detached)"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "  ContentFile            -- Text file (will not be over written if detached)"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "Note: All non-fatal invalid options for this specific command will be ignored."
         Wscript.Stdout.Writeline

      Case Else
         Wscript.Stdout.Writeline "Internal script error: Unknown help state (Command = " & CStr(Command) & ")."
         Wscript.Quit(-2)

   End Select

   Wscript.Quit(-1)

End Sub ' Конец DisplayUsage
' Конец примера

Требования:

Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше. Необходим отдельный пакет capicom, распространяемый Microsoft для ОС Windows.


Пример зашифрования и расшифрования при помощи CAPICOM

Данный пример демонстрирует зашифрование и расшифрование текстового документа при помощи инструментария CAPICOM.

'------------------------------------------------------------------------------
' В данном script-примере осуществляется зашифрование и расшифрование
' содержимого файла при помощи инструментария CAPICOM.
'------------------------------------------------------------------------------

Option Explicit

Const ForReading = 1, ForWriting = 2

' Команды.
Const Unknown                                      = 0
Const Encrypt                                      = 1
Const Decrypt                                      = 2

' CAPICOM константы.
Const CAPICOM_CURRENT_USER_STORE                   = 2

Const CAPICOM_CERTIFICATE_FIND_TIME_VALID          = 9

Const CAPICOM_ENCRYPTION_ALGORITHM_RC2             = 0

Const CAPICOM_ENCRYPTION_KEY_LENGTH_MAXIMUM        = 0

' Аргументы командной строки.
Dim Command       : Command        = Unknown
Dim StoreLocation : StoreLocation  = CAPICOM_CURRENT_USER_STORE
Dim StoreName     : StoreName      = "MY"
Dim CertFile      : CertFile       = Null
Dim Algorithm     : Algorithm      = Null 'CAPICOM_ENCRYPTION_ALGORITHM_RC2 - в CryptoPro CSP не поддерживается
Dim KeyLength     : KeyLength      = Null 'CAPICOM_ENCRYPTION_KEY_LENGTH_MAXIMUM - в CryptoPro CSP не поддерживается
Dim FileNames()

' В первую очередь осуществляется проверка того, что script выполняется при помощи CScript.exe.
If InStr(1, UCase(Wscript.FullName), "CSCRIPT.EXE", vbTextCompare) = 0 Then
   Wscript.Echo "This script can only be executed by CScript.exe." & vbCRLF & vbCRLF &_
                "You can either:" & vbCRLF & vbCRLF & _
                "1. Set CScript.exe as the default (Run CScript //h:cscript), or" & vbCRLF & _
                "2. Run CScript.exe directly as in, CScript " & Wscript.ScriptName & "."
   Wscript.Quit(-1)
End If

' Разбор командной сроки.
ParseCommandLine

' Поиск сертификата (сертификатов) получателя.
Dim Certificates
If Command = Encrypt Then

   ' Открытие хранилища сертификатов.
   Dim Store
   Set Store = CreateObject("CAPICOM.Store")
   Store.Open StoreLocation, StoreName

  ' В качестве кандитатов на сертификаты получателя
  ' изначально определяются все сертификаты хранилища.
   Set Certificates = Store.Certificates

   ' Из них выбираются только сертификаты, действительные в настоящее время.
   If Certificates.Count > 0 Then
      Set Certificates = Certificates.Find(CAPICOM_CERTIFICATE_FIND_TIME_VALID, Now)
   End If

   ' Выбор сертификата (сертификатов). Если после проведенной фильтрации осталось несколько кандидатов,
   ' то пользователю предоставляется выбор одного из них или нескольких (при помощи диалогового окна).
   Select Case Certificates.Count
   Case 0
      Wscript.Stdout.Writeline "Error: No recipient's certificate can be found."
      Wscript.Quit(1)

   Case 1
      ' Остался только один, потому он и будет использоваться.

   Case Else
      ' Пользователь выбирает сертификат (сертификаты) получателя.
      Set Certificates = Certificates.Select("CEnvelop.vbs", "Please select one or more recipient's certificate(s).", True)
      If Certificates.Count = 0 Then
         Wscript.Stdout.Writeline "Error: Certificate selection dialog was cancelled."
         Wscript.Quit(2)
      End If

   End Select

   ' Освобождение ресурсов.
   Set Store = Nothing
End If

' Выполнение требуемой операции.
Select Case Command
Case Encrypt
   DoEncryptCommand FileNames, Certificates, Algorithm, KeyLength

Case Decrypt
   DoDecryptCommand FileNames

End Select

' Освобождение ресурсов.
Set Certificates = Nothing

Wscript.Quit(0)

' Конец Main

'------------------------------------------------------------------------------
' Функиция DoSignCommand  зашифровывает содержимое файла FileNames(0)
' и записывает зашифрованные данные в FileNames(1).
'------------------------------------------------------------------------------

Sub DoEncryptCommand (FileNames, Certificates, Algorithm, KeyLength)
   Dim Content
   Dim Message
   Dim EnvelopedData

   ' Создание объекта EnvelopedData.
   Set EnvelopedData = CreateObject("CAPICOM.EnvelopedData")

   ' Определение алгоритма и размера ключа зашифрования.
   'EnvelopedData.Algorithm.Name = Algorithm - в CryptoPro CSP не поддерживается
   'EnvelopedData.Algorithm.KeyLength = KeyLength - - в CryptoPro CSP не поддерживается

   ' Добавление получателей.
   Dim Recipient
   For Each Recipient In Certificates
      EnvelopedData.Recipients.Add Recipient
   Next

   ' Распечатка информативного сообщения.
   Wscript.Stdout.Writeline "Enveloping text file " & FileNames(0) & "."
   Wscript.Stdout.Writeline

   ' Загрузка содержимого текстового файла для зашифрования.
   LoadFile FileNames(0), Content

   ' Зашифрование.
   EnvelopedData.Content = Content
   Message = EnvelopedData.Encrypt

   ' Сохранение зашифрованных данных в FileNames(1).
   SaveFile FileNames(1), Message
   Wscript.Stdout.Writeline "Successful - Enveloped message saved to " & FileNames(1) & "."

   ' Освобождение ресурсов.
   Set EnvelopedData = Nothing

End Sub ' Конец DoEncryptCommand

'------------------------------------------------------------------------------
' Функция DoCoSignCommand расшифровывает зашифрованный файл FileNames(0)и сохраняет
' расшифрвоанные данные в FileNames(1).
'------------------------------------------------------------------------------

Sub DoDecryptCommand (FileNames)
   Dim Message
   Dim EnvelopedData

   ' Создание объекта EnvelopedData.
   Set EnvelopedData = CreateObject("CAPICOM.EnvelopedData")

   ' Распечатка информативного сообщения.
   Wscript.Stdout.Writeline "Decrypting enveloped text file " & FileNames(0) & "."
   Wscript.Stdout.Writeline

   ' Загрузка зашифрованных данных.
   LoadFile FileNames(0), Message

   ' Расшифрование.
   EnvelopedData.Decrypt(Message)

   ' Сохранение расшифрованных данных в FileNames(1).
   SaveFile FileNames(1), EnvelopedData.Content
   Wscript.Stdout.Writeline "Successful - Decrypted content saved to " & FileNames(1) & "."

   ' Освобождение ресурсов.
   Set EnvelopedData = Nothing

End Sub ' Конец DoDecryptCommand

'------------------------------------------------------------------------------
'Функция LoadFile читает содержимое текстового файла.
'------------------------------------------------------------------------------

Sub LoadFile (FileName, Buffer)
    Dim fso
    Set fso = CreateObject("Scripting.FileSystemObject")

    If Not fso.FileExists(FileName) Then
        Wscript.Stdout.Writeline "Error: File " & FileName & " not found."
        Wscript.Quit(-5)
    End If

    Dim ts
    Set ts = fso.OpenTextFile(FileName, ForReading)
    Buffer = ts.ReadAll

End Sub ' Конец LoadFile

'------------------------------------------------------------------------------
' Функция SaveFile сохраняет строку в файл.
'------------------------------------------------------------------------------

Sub SaveFile (FileName, Buffer)
    Dim fso
    Set fso = CreateObject("Scripting.FileSystemObject")

    Dim ts
    Set ts = fso.OpenTextFile(FileName, ForWriting, True)
    ts.Write Buffer

End Sub ' End SaveFile

'------------------------------------------------------------------------------
' Функция ParseCommandLine разбирает командную строку и устанавливает
' опции согласно ей.
'------------------------------------------------------------------------------

Sub ParseCommandLine

   ' Константы для разбора состояний, задаваемых командной строкой.
   Const ARG_STATE_COMMAND    = 0
   Const ARG_STATE_OPTIONS    = 1
   Const ARG_STATE_FILENAME   = 8

   ' Разбор командной строки.
   Dim Arg
   Dim ArgState : ArgState = ARG_STATE_COMMAND

   For Each Arg In Wscript.Arguments
      Select Case ArgState
      Case ARG_STATE_COMMAND
         Select Case UCase(Arg)
         Case "ENCRYPT"
            Command = Encrypt

         Case "DECRYPT"
            Command = Decrypt

         Case Else
            DisplayUsage

         End Select

         ArgState = ARG_STATE_OPTIONS

      Case ARG_STATE_OPTIONS
         Select Case UCase(Arg)

         Case "-?", "/?"
            DisplayUsage

         Case Else
            If Left(Arg, 1) = "-"  OR Left(Arg, 1) = "/" Then
               DisplayUsage
            Else
               ReDim FileNames(0)
               FileNames(0) = Arg
            End If
            ArgState = ARG_STATE_FILENAME

         End Select

      Case ARG_STATE_FILENAME
         If Left(Arg, 1) = "-"  OR Left(Arg, 1) = "/" Then
            DisplayUsage
         Else
            ReDim Preserve FileNames(UBound(FileNames) + 1)
         End If

         FileNames(UBound(FileNames)) = Arg

      Case Else
         Wscript.Stdout.Writeline "Internal script error: Unknown argument state (" & CStr(ArgState) & ") encountered."
         Wscript.Quit(-3)

      End Select
   Next

   ' Проверка правильности состояния.
   If ArgState <> ARG_STATE_FILENAME Then
      DisplayUsage
   End If

   ' Проверка опций.
   Select Case Command
   Case Encrypt

      ' Функция зашифрвоаниядолжна иметь входной и выходной файлы.
      If (UBound(FileNames) - LBound(FileNames) + 1) <> 2 Then
         DisplayUsage
      End If

   Case Decrypt
      ' Функция расшифрования должна иметь входной и выходной файлы.
      If (UBound(FileNames) - LBound(FileNames) + 1) <> 2 Then
         DisplayUsage
      End If

   End Select

End Sub ' Конец ParseCommandLine

'------------------------------------------------------------------------------
' Функция DisplayUsage распечатывает информацию об использовании данного
' примера, и затем осуществляет выход с ошибкой.
'------------------------------------------------------------------------------

Sub DisplayUsage

   Select Case Command
      Case Unknown
         Wscript.Stdout.Writeline "Usage: CEnvelop Command InFile OutFile"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "Command:"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "  Encrypt                    -- Envelop a text file"
         Wscript.Stdout.Writeline "  Decrypt                    -- Decrypt an enveloped text file"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "For help on a specific command, enter ""CEnvelop Command -?"""

      Case Encrypt
         Wscript.Stdout.Writeline "Usage: CEnvelop Encrypt ContentFile EnvelopedFile"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "The Encrypt command is used to envelop a text file to multiple recipients, of"
         Wscript.Stdout.Writeline "which the certificates must either reside in the AddressBook store, or in the"
         Wscript.Stdout.Writeline "specified certificate file. Enveloping protects the data from being read by"
         Wscript.Stdout.Writeline "others except the intended recipients."
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "Parameters:"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "  -?                         -- This help screen"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "  ContentFile                -- Text file to be enveloped"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "  EnvelopedFile              -- Enveloped text file"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "Note: All non-fatal invalid options for this specific command will be ignored,"
         Wscript.Stdout.Writeline "      and the ** symbol indicates option can be listed multiple times."
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "      If there is only one certificate found matching the requirement, that"
         Wscript.Stdout.Writeline "      particular certificate will be used as the recipient's certificate."
         Wscript.Stdout.Writeline "      However, if there is more than one certificate matching the requirement,"
         Wscript.Stdout.Writeline "      a dialog will be displayed to allow selection of multiple recipient's"
         Wscript.Stdout.Writeline "      certificates."
         Wscript.Stdout.Writeline

       Case Decrypt
         Wscript.Stdout.Writeline "Usage: CEnvelop Decrypt EnvelopedFile ContentFile"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "The Decrypt command is used to decrypt an enveloped text file. The decryption"
         Wscript.Stdout.Writeline "process will automatically search for the recipient's certificate in MY store"
         Wscript.Stdout.Writeline "(Current User or Local Machine)."
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "Parameters:"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "  -?                         -- This help screen"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "  EnvelopedFile              -- Enveloped text file"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "  ContentFile                -- Decrypted text file"
         Wscript.Stdout.Writeline
         Wscript.Stdout.Writeline "Note: All non-fatal invalid options for this specific command will be ignored."
         Wscript.Stdout.Writeline

      Case Else
         Wscript.Stdout.Writeline "Internal script error: Unknown help state (Command = " & CStr(Command) & ")."
         Wscript.Quit(-2)

   End Select

   Wscript.Quit(-1)

End Sub ' Конец DisplayUsage
' Конец примера

Требования:

Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше. Необходим отдельный пакет capicom, распространяемый Microsoft для ОС Windows.


Примеры использования криптопровайдера совместно с функциями CEnroll.

В данном разделе приводятся примеры, демонстрирующие использование функций CEnroll для реализации операций с криптопровайдером.

  • Пример создания запроса на сертификат


Пример создания запроса на сертификат

Данный пример демонстрирует осуществление создания запроса на сертификат при помощи инструментария CEnroll.

'------------------------------------------------------------------------------
' В данном script-примере создается запрос на сертификат
' в кодировке base64 PKCS10 при помощи инструментария CEnroll.
'------------------------------------------------------------------------------

' Идентификационное имя запроса.
Dim strDN

' Запрос.
Dim strReq

' CEnroll Объект
Dim objXen

' Обработка ошибок.
On Error Resume Next

' Создание объекта.
Set objXen = CreateObject("CEnroll.CEnroll.1")

' Создание идентификационного имени.
strDN =  "CN=UserName" _
      & ",OU=UserUnit" _
      & ",O=CRYPTO-PRO" _
      & ",L=MOSCOW" _
      & ",S=WA" _
      & ",C=RU"

'Опредление типа провайдера
objXen.ProviderType = 75

'Определение имени провайдера
objXen.ProviderName = "Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider"

' Создание запроса PKCS #10.
MsgBox("Creating PKCS #10 " & strDN)
strReq = objXen.createPKCS10( strDN, "1.3.6.1.4.1.311.2.1.21")

' Если запрос не создан - сообщение об ошибке.
if ( Err.Number <> 0 ) then
    MsgBox("Error in call to createPKCS10 " & Err.Number)
    err.clear
else
' Если запрос создан - вывод на экран и запись в файл этого запроса.
    MsgBox("Submitting request " & strReq)
    Dim fso, MyFile
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set MyFile = fso.CreateTextFile("c:\testfile.txt", True)
    MyFile.Write strReq
    MyFile.Close
end if

Wscript.Quit(0)
' Конец примера

Требования:

Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.


Управление алгоритмами и параметрами RFC 4357

Управление алгоритмами и параметрами RFC 4357 в СКЗИ КриптоПро CSP.

В СКЗИ КриптоПро CSP используются алгоритмы низкого уровня и параметры российских криптографических стандартов, определенные в RFC 4357.

В данном разделе приводятся основные способы использования функций СКЗИ для управления этими элементами.

Пункт RFC 4357 | Управление с помощью СКЗИ КриптоПро CSP
2.1. GOST 28147-89 CBC Mode

DWORD dwMode = CRYPT_MODE_CBC;
CPSetKeyParam(hProv, hSessionKey, KP_MODE, (BYTE*)& dwMode, 0);
2.2. GOST 28147-89 Padding Modes: Zero padding

DWORD dwPadding = ZERO_PADDING;
CPSetKeyParam(hProv, hSessionKey, KP_PADDING, (BYTE*)& dwPadding, 0);
2.2. GOST 28147-89 Padding Modes: PKCS#5 padding

DWORD dwPadding = PKCS5_PADDING;
CPSetKeyParam(hProv, hSessionKey, KP_PADDING, (BYTE*)& dwPadding, 0);
2.2. GOST 28147-89 Padding Modes: Random padding

DWORD dwPadding = RANDOM_PADDING;
CPSetKeyParam(hProv, hSessionKey, KP_PADDING, (BYTE*)& dwPadding, 0);
2.3.1. Null Key Meshing

DWORD dwMixmodeon = 0;
CPSetKeyParam(hProv, hSessionKey, KP_MIXMODE, (BYTE*)& dwMixmodeon, 0);
2.3.2. CryptoPro Key Meshing

DWORD dwMixmodeon = 1;
CPSetKeyParam(hProv, hSessionKey, KP_MIXMODE, (BYTE*)& dwMixmodeon, 0);
3. HMAC_GOSTR3411

CPCreateHash(hProv, CALG_GR3411_HMAC, hSessionKey, 0, &hHMAC);
// ...
CPHashData(hProv, hHMAC, pbInput, dwInputLen, 0);
// ...
CPGetHashParam(hProv, hHMAC, HP_HASHVAL, pbHMAC, &cbHMAC, 0);
4. PRF_GOSTR3411

CPCreateHash(hProv, CALG_TLS1PRF, hKey, 0, &hHash);
CPSetHashParam(hProv, hHash, HP_TLS1PRF_LABEL, pbLabel, 0));
CPSetHashParam(hProv, hHash, HP_TLS1PRF_SEED, pbSeed, 0));
CPGetHashParam(hProv, hHash, HP_HASHVAL, pbPRF, &cbPRF, 0));

В протоколе TLS PRF используется также для порождения сессионных ключей из мастер-ключа CALG_TLS1_MASTER и объекта хэширования CALG_TLS1_MASTER_HASH.

Примечание: с помощью приведенного кода возможно порождение выхода PRF длиной не более 32 байта. Для порождения выхода PRF большей длины можно воспользоваться кодом, приведенным ниже после таблицы.

5.1. VKO GOST R 34.10-94 | В КриптоПро CSP версий 3.6.1 и выше не поддерживается.
5.2. VKO GOST R 34.10-2001

ALG_ID alg = CALG_G28147;
// ...
CPImportKey(hProvSender, pbKeyBlobResponder, dwBlobLenResponder, hSenderKey, 0, &hAgreeKey);
CPSetKeyParam(hProv, hAgreeKey, KP_IV, pbIV, 0);
CPSetKeyParam(hProv, hAgreeKey, KP_ALGID, (BYTE*)&alg, 0);
6.1. GOST 28147-89 Key Wrap

ALG_ID alg = CALG_SIMPLE_EXPORT;
// ...
CPSetKeyParam(hProv, hExportKey, KP_ALGID, (LPBYTE)&alg, 0);
// ...
CPExportKey(hProv, hWrappedKey, hExportKey, PRIVATEKEYBLOB, 0, (BYTE*)pbKeyBlob, &dwKeyBlobLen);
6.2. GOST 28147-89 Key Unwrap

ALG_ID alg = CALG_SIMPLE_EXPORT;
// ...
CPSetKeyParam(hProv, hImportKey, KP_ALGID, (LPBYTE)&alg, 0);
// ...
CPImportKey(hProv, (BYTE*)pbKeyBlob, dwKeyBlobLen, hImportKey, 0, &hUnwrappedKey);
6.3. CryptoPro Key Wrap

ALG_ID alg = CALG_PRO_EXPORT;
// ...
CPSetKeyParam(hProv, hExportKey, KP_ALGID, (LPBYTE)&alg, 0);
// ...
CPExportKey(hProv, hWrappedKey, hExportKey, PRIVATEKEYBLOB, 0, (BYTE*)pbKeyBlob, &dwKeyBlobLen);
6.4. CryptoPro Key Unwrap

ALG_ID alg = CALG_PRO_EXPORT;
// ...
CPSetKeyParam(hProv, hImportKey, KP_ALGID, (LPBYTE)&alg, 0);
// ...
CPImportKey(hProv, (BYTE*)pbKeyBlob, dwKeyBlobLen, hImportKey, 0, &hUnwrappedKey);
6.5. CryptoPro KEK Diversification Algorithm | Производится в рамках «6.3. CryptoPro Key Wrap» и «6.4. CryptoPro Key Unwrap».
7. Secret Key Diversification

BYTE* DiversData;// Указатель на диверсифицирующую последовательность.
DWORD dwDiversLen;// Длина диверсифицирующей последовательности.
LPCRYPT_DIVERSBLOB Blob;
DWORD dwBlobLen;
// ...
dwBlobLen = sizeof(CRYPT_DIVERSBLOBHEADER)+sizeof(BLOBHEADER)+dwDiversLen;
Blob->DiversBlobHeader.BlobHeader.bType = (BYTE)DIVERSKEYBLOB;
Blob->DiversBlobHeader.BlobHeader.bVersion = (BYTE)BLOB_VERSION;
Blob->DiversBlobHeader.BlobHeader.reserved = (WORD)0;
Blob->DiversBlobHeader.BlobHeader.aiKeyAlg = CALG_G28147;
Blob->DiversBlobHeader.aiDiversAlgId = CALG_PRO_DIVERS;
Blob->DiversBlobHeader.dwDiversMagic = DIVERS_MAGIC;
Blob->DiversBlobHeader.cbDiversData = dwDiversLen;
CopyMemory(Blob->bDiversData,Diversdata,dwDiversLen);
CPImportKey(hProv, (BYTE*)pbDivers, dwBlobLen, hKey, 0, &hDiversKey);
8. Algorithm Parameters
  • id-Gost28147-89-TestParamSet
  • id-Gost28147-89-CryptoPro-A-ParamSet
  • id-Gost28147-89-CryptoPro-B-ParamSet
  • id-Gost28147-89-CryptoPro-C-ParamSet
  • id-Gost28147-89-CryptoPro-D-ParamSet

Установка: CPSetKeyParam(hProv, hSessionKey, KP_OID, (BYTE*) oid,0));

  • szOID_Gost28147_89_TestParamSet
  • szOID_Gost28147_89_CryptoPro_A_ParamSet
  • szOID_Gost28147_89_CryptoPro_B_ParamSet
  • szOID_Gost28147_89_CryptoPro_C_ParamSet
  • szOID_Gost28147_89_CryptoPro_D_ParamSet

8. Algorithm Parameters

  • id-GostR3411-94-TestParamSet
  • id-GostR3411-94-CryptoProParamSet

Установка: CPSetHashParam(hProv, hHash, HP_OID, (BYTE*)oid, 0));

  • szOID_GostR3411_94_TestParamSet
  • szOID_GostR3411_94_CryptoProParamSet

8. Algorithm Parameters

  • id-GostR3410-94-TestParamSet
  • id-GostR3410-94-CryptoPro-A-ParamSet
  • id-GostR3410-94-CryptoPro-B-ParamSet
  • id-GostR3410-94-CryptoPro-C-ParamSet
  • id-GostR3410-94-CryptoPro-D-ParamSet
  • id-GostR3410-94-CryptoPro-XchA-ParamSet
  • id-GostR3410-94-CryptoPro-XchB-ParamSet
  • id-GostR3410-94-CryptoPro-XchC-ParamSet

В КриптоПро CSP версий 3.6.1 и выше не поддерживается.

8. Algorithm Parameters

  • id-GostR3410-2001-TestParamSet
  • id-GostR3410-2001-CryptoPro-A-ParamSet
  • id-GostR3410-2001-CryptoPro-B-ParamSet
  • id-GostR3410-2001-CryptoPro-C-ParamSet
  • id-GostR3410-2001-CryptoPro-XchA-ParamSet
  • id-GostR3410-2001-CryptoPro-XchB-ParamSet

Установка: CPSetKeyParam(hProv, hPrivKey, KP_OID, (BYTE*) oid,0));

  • szOID_GostR3410_2001_TestParamSet
  • szOID_GostR3410_2001_CryptoPro_A_ParamSet
  • szOID_GostR3410_2001_CryptoPro_B_ParamSet
  • szOID_GostR3410_2001_CryptoPro_C_ParamSet
  • szOID_GostR3410_2001_CryptoPro_XchA_ParamSet
  • szOID_GostR3410_2001_CryptoPro_XchB_ParamSet

Вычисление PRF (к пункту "4. PRF_GOSTR3411")

void GR3411_HMAC_(HCRYPTPROV hCont,HCRYPTKEY hKey,DATA_BLOB *pData,DWORD cData,BYTE *pbDigest,DWORD *pdwDigestLen)
{
    unsigned int i;
    HCRYPTHASH hHmac;
    DWORD q=32;

    if(!CPCreateHash(hCont, CALG_GR3411_HMAC,hKey,0,&hHmac))
        HandleError("Error in CreateHash");

    for (i=0;i<cData;i++)
        if(!CPHashData(hCont, hHmac,(LPBYTE)pData[i].pbData,pData[i].cbData,0))
            HandleError("Error during CPHashData");

    if(!CPGetHashParam(hCont, hHmac, HP_HASHVAL, (LPBYTE)pbDigest, &q, 0))
        HandleError("Error during CPGetHashParam");

    *pdwDigestLen = q;
     CPDestroyHash(hCont, hHmac);
}

void
GR3411_PRF (
    HCRYPTPROV  hCont,
    HCRYPTKEY   hKey,
    DATA_BLOB   *pData,
    DWORD        cData,
    BYTE        *pbDigest,
    DWORD       dwDigestLen)
{
    BYTE A1[32];
    DWORD hmac_len = sizeof(A1);
    LPBYTE out = pbDigest;
    DWORD olen = dwDigestLen;
    HRESULT res = S_OK;
    DATA_BLOB * pExtData = malloc((cData+1)*sizeof(DATA_BLOB));

    GR3411_HMAC_(hCont, hKey, pData, cData, A, &hmac_len);
    pExtData->pbData = A;
    pExtData->cbData = hmac_len;
    CopyMemory (pExtData+1, pData, cData*sizeof(DATA_BLOB));
    while(olen>hmac_len)
    {
        GR3411_HMAC_ (hCont, hKey, pExtData, 1+cData, out, &hmac_len);
        out+=hmac_len;
        olen-=hmac_len;
        GR3411_HMAC_(hCont, hKey, pExtData, 1, A, &hmac_len);
    }
    GR3411_HMAC_ (hCont, hKey, pExtData, 1+cData, A, &hmac_len);
    CopyMemory (out, A, olen);
    free(pExtData);
}


Основные отличия интерфейса КриптоПро CSP версии 4.0 от версии 3.6

Основные отличия интерфейса КриптоПро CSP версии 4.0 от версии 3.6.

В данном разделе приведена краткая справка об основных изменениях в СКЗИ КриптоПро CSP при работе с уровня CryptoAPI 1.0.

Три типа провайдера

Основным отличием СКЗИ КриптоПро CSP версии 4.0 от предыдущих версий является поддержка стандартов ГОСТ Р 34.11-2012 (алгоритм хэширования) и ГОСТ Р 34.10-2012 (алгоритмы формирования и проверки электронной подписи), потребовавшая введения двух новых типов провайдера (PROV_GOST_2012_256 и PROV_GOST_2012_512) в дополнение к ранее существовавшему PROV_GOST_2001_DH. При создании контекста с помощью вызова функции CPAcquireContext() тип провайдера должен быть указан в поле dwProvType структуры PVTABLEPROVSTRUC.

Соответствие между типами провайдера и алгоритмами долговременных ключевых пар

Тип провайдера, указанный при создании контекста, однозначным образом определяет алгоритмы ключевых пар, сохраняемых в контейнере.

  • Провайдер типа PROV_GOST_2001_DH создает ключи алгоритма ГОСТ Р 34.10-2001.
  • Провайдер типа PROV_GOST_2012_256 создает ключи алгоритма ГОСТ Р 34.10-2012 длины 256 бит (длина открытого ключа 512 бит).
  • Провайдер типа PROV_GOST_2012_512 создает ключи алгоритма ГОСТ Р 34.10-2012 длины 512 бит (длина открытого ключа 1024 бита).

Соответствие между типом провайдера и параметрами шифрования

Тип провайдера также определяет набор узлов замены алгоритма шифрования ГОСТ 28147-89, используемый по умолчанию.

  • При создании сессионного ключа CALG_G28147 с помощью функции CPGenKey() или CPDeriveKey() с использованием провайдера типа PROV_GOST_2001_DH, PROV_GOST_2012_256 или PROV_GOST_2012_512 параметр KP_CIPHEROID полученного ключа по умолчанию принимает установленное для провайдера значение PP_CIPHEROID, либо, после загрузки ключей с контейнера (с помощью CPGetUserKey()), oid параметров шифрования, установленный в этом контейнере.
  • При использовании алгоритма VKO GOST R 34.10-2001 (дополненный алгоритм Диффи-Хеллмана с использованием функции хэширования ГОСТ Р 34.11-94) с долговременным ключом параметр KP_CIPHEROID полученного ключа принимает oid параметров шифрования, установленный в соответствующем долговременному ключу контейнере.
  • При использовании алгоритма VKO GOST R 34.10-2001 (дополненный алгоритм Диффи-Хеллмана с использованием функции хэширования ГОСТ Р 34.11-94) с эфемерным ключом параметр KP_CIPHEROID полученного ключа принимает установленное для провайдера значение PP_CIPHEROID.
  • При использовании алгоритма VKO GOST R 34.10-2012-256 (дополненный алгоритм Диффи-Хеллмана с использованием функции хэширования ГОСТ Р 34.11-2012 с длиной выхода 256 бит) параметр KP_CIPHEROID полученного ключа принимает значение, установленное в параметрах импортируемого открытого ключа (уточнение: в отличие от остальных случаев при использовании параметров "1.2.643.7.1.2.5.1.1" (вариант ТК26 Z) параметры шифрования в экспортированном открытом ключе явно не указываются, поэтому отсутствие в импортируемом открытом ключе установленных параметров шифрования трактуется как применение параметров "1.2.643.7.1.2.5.1.1" (вариант ТК26 Z) ).
  • Параметры шифрования (PP_CIPHEROID) для PROV_GOST_2001_DH по умолчанию устанавливаются как "1.2.643.2.2.31.1", вариант "Верба-О" (в контрольной панели описаны как "параметры по умолчанию"); для PROV_GOST_2012_256 или PROV_GOST_2012_512 как "1.2.643.7.1.2.5.1.1", вариант ТК26 Z.
  • При использовании ключей ГОСТ Р 34.10-2012 длиной 256 бит с провайдером PROV_GOST_2001_DH применяется тот же порядок выбора узлов замены, что и для провайдера PROV_GOST_2012_256.
  • При использовании ключей ГОСТ Р 34.10-2001 с провайдером PROV_GOST_2012_256 применяется тот же порядок выбора узлов замены, что и для провайдера PROV_GOST_2001_DH.

Отличия в использовании ключей алгоритмов ГОСТ Р 34.10-2001 и ГОСТ Р 34.10-2012

При использовании ключей алгоритмов ГОСТ Р 34.10-2001 и ГОСТ Р 34.10-2012 существуют следующие отличия.

  • При использовании ключей алгоритма ГОСТ Р 34.10-2001 для формирования или проверки электронной подписи необходимо использовать алгоритм хэширования ГОСТ Р 34.11-94.
  • При использовании ключей алгоритма ГОСТ Р 34.10-2012 длины 256 бит для формирования или проверки электронной подписи необходимо использовать алгоритм хэширования ГОСТ Р 34.11-2012 (256 бит).
  • При использовании ключей алгоритма ГОСТ Р 34.10-2012 длины 512 бит для формирования или проверки электронной подписи необходимо использовать алгоритм хэширования ГОСТ Р 34.11-2012 (512 бит).
  • Долговременные ключи ГОСТ Р 34.10-2001 могут быть экспортированы при помощи алгоритмов CALG_PRO_EXPORT и CALG_PRO12_EXPORT.

  • Долговременные ключи ГОСТ Р 34.10-2012 могут быть экспортированы только при помощи алгоритма CALG_PRO12_EXPORT.

    Заметим, что для экспорта сессионных ключей могут использоваться алгоритмы CALG_SIMPLE_EXPORT, CALG_PRO_EXPORT и CALG_PRO12_EXPORT.

Установка параметров ключей алгоритмов электронной подписи и Диффи-Хеллмана

Идентификаторы параметров долговременных и эфемерных ключей электронной подписи и Диффи-Хеллмана, соответствующих используемому типу провайдера, могут быть установлены и/или получены с использованием функций CPGetProvParam() / CPSetProvParam() и CPSetKeyParam() / CPGetKeyParam() с флагами PP_SIGNATUREOID/PP_DHOID и KP_DHOID соответственно. Для создания эфемерных ключей, не соответствующих используемому типу провайдера, с необходимыми параметрами необходимо сначала устанавливать данные параметры явным образом с использованием функции SetKeyParam с параметром KP_DHOID, после чего выработать значение ключа с помощью функции CPSetKeyParam() с параметром KP_X. Внимание! Параметры эфемерных ключей, не соответствующих типу провайдера, по умолчанию не определены.


Основные особенности отображения пользовательского UI

Использование CryptoAPI в "тихом" режиме.

В данном разделе описаны ситуации, когда может потребоваться "тихий" режим, а также о том, как его использовать.

Суть проблемы

В ряде случаев требуется минимизировать взаимодействие с пользователем. При использовании CryptoAPI в некоторых случаях может потребоваться действие пользователя:

  • Если не указано полное имя контейнера.
  • Если для генерации ключа используется БиоДСЧ или другой, требующий действий пользователя.
  • Если требуется ввод пин-кода или аналогичное действие для осуществления аутентификации.
  • Если провайдер должен отобразить окно с критической информацией (лицензия недействительна или отсутствует, срок действия алгоритма заканчивается и т.д.).
"Тихий" режим позволяет выполнить операцию без взаимодействия с пользователем.

Как заставить программу работать в "тихом" режиме

Существуют несколько способов:

  • Указать необходимую информацию полностью. Например, указать пин-код перед выполняемой операцией или полное имя контейнера наподобие \\.\REGISTRY\test_container (см. "Имя контейнера")).
  • Использовать генераторы, не требующие взаимодейстия с пользователем (например, аппаратные или КриптоПро Исходный Материал).
  • Решить проблему, по причине которой провайдер выбрасывал окна (например, ввести лицензию).
  • Использовать соответствующие флаги в CryptoAPI функциях:
    • CryptAcquireContext - CRYPT_SILENT
      Можно задать этот флаг глобально для всех операций:
      на 32-х битной Windows выполнить в коммандной строке с правами администратора:
      reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Crypto Pro\Cryptography\CurrentVersion\Parameters" /v force_silent /t REG_DWORD /d 1 /f
      на 64-х битной Windows выполнить в коммандной строке с правами администратора:
      reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Crypto Pro\Cryptography\CurrentVersion\Parameters" /v force_silent /t REG_DWORD /d 1 /f
      для остальных ОС выполнить в консоли с правами администратора из папки, содержащей утилиту cpconfig:
      ./cpconfig -ini '' -add long force_silent 1
      Если дальнейшие вызовы функций криптопровайдера требуют отображения графического интерфейса, то криптопровайдер возвратит ошибку NTE_SILENT_CONTEXT.
    • CryptAcquireCertificatePrivateKey - CRYPT_ACQUIRE_SILENT_FLAG
    • CryptSignMessage - CRYPT_MESSAGE_SILENT_KEYSET_FLAG в dwFlags структуры CRYPT_SIGN_MESSAGE_PARA
    • CryptDecryptMessage - CRYPT_MESSAGE_SILENT_KEYSET_FLAG в dwFlags структуры CRYPT_DECRYPT_MESSAGE_PARA
В утилитах реализован ключ -silent, который позволяет выполнить операцию в "тихом" режиме.


Copyright

Авторские права на средство криптографической защиты информации "КриптоПро CSP 4.0" и эксплуатационную документацию зарегистрированы в Российском агентстве по патентам и товарным знакам (Роспатент). Свидетельство об официальной регистрации программ для ЭВМ № 2001610275 от 14 марта 2001 года.

Документ входит в комплект поставки программного обеспечения "КриптоПро CSP 4.0", на него распространяются все условия лицензионного соглашения. Без специального письменного разрешения OOO "Крипто-Про" документ или его часть в электронном или печатном виде не могут быть скопированы и переданы третьим лицам с коммерческой целью.


Список требований

Структуры данных _CONTAINER_EXTENSION

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_CACHE_SIZE

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_DIVERSBLOB

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_DIVERSBLOBHEADER

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_ENUMREADER_INFO

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_ENUMREADER_INFO_MEDIA

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_FKC_DH_CHECK

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_FKC_EKE_AUTH_INFO_PARAM

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_FKC_PIN_INFO

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_FKC_PIN_INFO_SOURCE

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_KDF_TREE_DIVERS_INFO

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_KDF_TREE_DIVERSBLOB

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_KDF_TREE_DIVERSBLOB_HEADER

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_NK_INFO_PARAM

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_OPAQUEBLOB

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_PASSWD_INFO_PARAM

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_PIN_INFO

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_PIN_INFO_SOURCE

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_PIN_NK_PARAM

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_PIN_PARAM

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_PRIVATEKEYBLOB

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_PUBKEY_INFO_HEADER

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_PUBKEYPARAM

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_PUBLICKEYBLOB

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_SIMPLEBLOB

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_SIMPLEBLOB_512

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _CRYPT_SIMPLEBLOB_HEADER

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Структуры данных _PUBLICKEYSTRUC

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Windows прототип описан в файле Wincrypt.h, Unix - CSP_Wincrypt.h

    • Глобальный CPCAcquireContext

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    Файл описания: Прототип описан в файле wincspc.h.

    Ядро ОС: При использовании в ядре ОС CPCAcquireContext допустимо вызывать только с флагами CRYPT_VERIFYCONTEXT|CRYPT_SILENT.

    • Глобальный CPCCreateProvider

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    Ядро ОС: При использовании в ядре ОС CPCAcquireContext допустимо вызывать только с флагами CRYPT_VERIFYCONTEXT|CRYPT_SILENT.

    • Глобальный CPCDestroyProvider

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Глобальный CPCGetProvParam

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Глобальный CPCReleaseContext

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Глобальный CPAcquireContext

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCAcquireContext .

    • Глобальный CPGetProvParam

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCGetProvParam .

    • Глобальный CPReleaseContext

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCReleaseContext .

    • Глобальный CPSetProvParam

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCSetProvParam .

    • Глобальный CPDeriveKey

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCDeriveKey .

    • Глобальный CPDestroyKey

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCDestroyKey .

    • Глобальный CPDuplicateKey

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCDuplicateKey .

    • Глобальный CPExportKey

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCExportKey .

    • Глобальный CPGenKey

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCGenKey .

    • Глобальный CPGenRandom

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCGenRandom .

    • Глобальный CPGetKeyParam

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCGetKeyParam .

    • Глобальный CPGetUserKey

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCGetUserKey .

    • Глобальный CPImportKey

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCImportKey .

    • Глобальный CPSetKeyParam

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCSetKeyParam .

    • Глобальный CPDecrypt

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCDecrypt .

    • Глобальный CPEncrypt

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCEncrypt .

    • Глобальный CPCreateHash

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCCreateHash .

    • Глобальный CPDestroyHash

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCDestroyHash .

    • Глобальный CPDuplicateHash

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCDuplicateHash .

    • Глобальный CPGetHashParam

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCGetHashParam .

    • Глобальный CPHashData

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCHashData .

    • Глобальный CPHashSessionKey

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCHashSessionKey .

    • Глобальный CPSetHashParam

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCSetHashParam .

    • Глобальный CPSignHash

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCSignHash .

    • Глобальный CPVerifySignature

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле wincsp.h.

    Ядро ОС: Вместо неё используется аналогичная функция CPCVerifySignature .

    • Глобальный CRYPT_FKC_DH_CHECK_VAL

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Файл описания: Прототип описан в файле WinCryptEx.h.

    • Глобальный CPCDeriveKey

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Глобальный CPCDestroyKey

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Глобальный CPCDuplicateKey

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Глобальный CPCExportKey

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    Ядро ОС: Поддерживается только типы SIMPLEBLOB и OPAQUEKEYBLOB.

    • Глобальный CPCGenKey

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    Ядро ОС: При использовании в ядре ОС CPCGenKey допустимо вызывать только для производства ключей сессии и эфемеральных ключей.

    • Глобальный CPCGenRandom

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    Ядро ОС: Перед получением случайных чисел требуется инициализировать ДСЧ контекста криптопровайдера hProv с помощью параметра PP_RANDOM функции CPCSetProvParam().

    • Глобальный CPCGetKeyParam

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Глобальный CPCGetUserKey

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Глобальный CPCImportKey

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Глобальный CPCSetKeyParam

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Глобальный CPCDecrypt

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Глобальный CPCEncrypt

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Глобальный CPCCreateHash

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Глобальный CPCDestroyHash

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Глобальный CPCDuplicateHash

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Глобальный CPCGetHashParam

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Глобальный CPCHashData

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Глобальный CPCHashSessionKey

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Глобальный CPCSetHashParam

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Глобальный CPCSignHash

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Глобальный CPCVerifySignature

  • Ядро FreeBSD: 7/8/9 или выше

    Ядро Linux: ядро 2.4.x/2.6.x/3.0.х/3.2.х или выше

    Ядро Solaris: 10/11 или выше.

    Ядро Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше.

    • Страница Пример на создание ключевого контейнера и генерацию ключей

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример использования функции CryptAcquireContext

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример на перечисление криптопровайдеров

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример на получение сессионного ключа из пароля

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример на дублирование сессионного ключа

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример на установку и получение сессионного ключа

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример на экспортирование сессионного ключа с использованием структуры BLOB

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример на экспортирование сессионного ключа с использованием сертификатами

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример на закодирование и раскодирование данных

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример на CryptEncryptMessage и CryptDecryptMessage

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример на копирование закрытого ключа

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример на работу в режиме SILENT, без окон

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример на создание хеша

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример на подпись объекта функции хеширования и проверку подписи

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример на дублирование хеша

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример использования объекта хэша PRFKEYMAT

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример на запись открытого ключа в файл

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример на зашифрование файла

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример на расшифрование файла

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример экспорта закрытого ключа в блоб

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример импорта закрытого ключа из блоба

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Пример поиска контейнера, соответствующего сертификату

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    Ядро Windows NT: не поддерживает.

    • Страница Шаблон XML-документа на подпись

  • Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше. Необходим MSXML 5.0.

    • Страница Шаблон XML-документа для создания двух подписей

  • Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше. Необходим MSXML 5.0.

    • Страница Пример создания подписи XML-документа

  • Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше. Необходим MSXML 5.0.

    • Страница Пример проверки подписи XML-документа

  • Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше. Необходим MSXML 5.0.

    • Страница Пример создания и проверки двух подписей XML-документа

  • Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше. Необходим MSXML 5.0.

    • Страница Пример подписи и проверки подписи при помощи CAPICOM

  • Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше. Необходим отдельный пакет capicom, распространяемый Microsoft для ОС Windows.

    • Страница Пример зашифрования и расшифрования при помощи CAPICOM

  • Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше. Необходим отдельный пакет capicom, распространяемый Microsoft для ОС Windows.

    • Страница Пример создания запроса на сертификат

  • Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    • Страница Функциональность

  • AIX: 5/6/7 или выше.

    FreeBSD: 7/8/9 или выше.

    Linux: LSB 3.1 (RHEL 4, SuSE 10) или выше.

    Solaris: 10 или выше.

    Mac OSX: 10.7/8 или выше.

    iOS: 6/7 или выше.

    Windows 2000 или выше: Необходимо Windows 2000 SP4 или старше с Internet Explorer 6.0 или старше.

    • КриптоПро CSP Версия: 4.0