Ранее в этой лекции уже упоминалось понятие криптопровайдера. Это концептуальная идея, лежащая в основе криптографической защиты операционных систем семейства Windows.
Криптопровайдер, или Cryptographic Service Provider (кратко - CSP), в ОС Windows – это библиотека криптографических алгоритмов, доступных прикладным программистам посредством интерфейса CryptoAPI (Cryptographic Application Programming Interface). При взаимодействии с CSP приложения вызывают функции CryptoAPI, которые обращаются к библиотекам Crypt32.dll и Advapi32.dll операционной системы. Последняя фильтрует вызовы этих функций и передаёт их далее соответствующим функциям CSP через CryptoSPI (Cryptographic System Program Interface).
CryptoAPI 1.0 это так называемый уровень криптографических примитивов - определенный набор функций реализующих основные криптографические операции — шифрование/расшифрование данных, хеширование данных, генерация и проверка электронной цифровой подписи (ЭЦП) и работу с ключевой информацией.
С точки зрения операционной системы криптопровайдер представляется как библиотека динамической линковки (dll). Набор экспортируемых функций этой библиотеки должен соответствовать интерфейсу криптопровайдера (cryptographic service provider interface —CryptoSPI), который приведен ниже в таблицах.
|
|
Таблица 6.1. – Группы функций интерфейс криптопровайдера CryptoSPI
Группа функций | Описание |
Инициализация и параметры криптопровайдера | Функции инициализации и параметры. Предназначены для установления сессии прикладного ПО с криптопровайдером и получения (установки) параметров сессии. |
Функции генерации и работы с ключами | Функции генерации и работы с ключами предназначены для генерации парных и обработки различных типов ключей, используемых в криптопровайдере. |
Функции шифрования/расшифрования данных | Функции шифрования/расшифрования данных предназначены для выполнения операций, шифрования и расшифрования данных. |
Функции хэширования и ЭЦП | Функции хэширования и ЭЦП предназначены для вычисления значения хэш‑функции и формирования/проверки ЭЦП данных. |
Интерфейс криптопровайдера стандартизирован с целью абстрагирования конечного приложения от конкретной реализации криптографических функций. Основной архитектурной особенностью криптографических ядер, разработанноых по принципу криптопровайдера, является то, что прикладное программное обеспечение не имеет непосредственного доступа к ключевой и криптографически-опасной информации. Все операции с сессионными и долговременными закрытыми и симметричными ключами, незавершёнными значениями хэш-функций и т. п. осуществляется через дескрипторы соответствующих объектов. Это позволяет обеспечить корректность операций над этими объектами, так как дескриптор объекта непосредственно не содержит его адреса.
|
|
Использующее криптопровайдер прикладное программное обеспечение вызывает «абстрактные» функции CryptoAPI 1.0, которые экспортируются системной библиотекой advapi32.dll. На рисунке (Рисунок 6.3) показана схема вызова функций CryptoAPI 1.0, и последующий вызов криптопровайдера.
Рисунок 6.3.– Схема вызова криптопровайдера
Функции, экспортируемые библиотекой advapi32.dll по параметрам фактически полностью совпадают с функциями экспортируемыми криптопровайдером. Параметрами, главным образом отличаются функция CryptoAPI 1.0 CryptAcquireContext() (Рисунок 6.4) и функция CryptoSPI CPAcquireContext() (Рисунок 6.5).
BOOL WINAPI CryptAcquireContext(
HCRYPTPROV *phProv,
LPCTSTR pszContainer,
LPCTSTR pszProvider,
DWORD dwProvType,
DWORD dwFlags
);
Рисунок 6.4. – Параметры вызова CryptAcquireContext()
BOOL CPAcquireContext(
HCRYPTPROV* phProv,
CHAR* pszContainer,
DWORD dwFlags,
PVTableProvStruc pVTable
);
Рисунок 6.5 – Параметры вызова CPAcquireContext()
В параметре pszProvider предается имя криптопровайдера. Имена всех зарегистрированных в системе криптопровайдеров находятся в разделе системного реестра:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\Defaults\Provider\
Имя папок в этом разделе имеет особый смысл. При вызове CryptAcquireContext() в этом разделе ищется папка имя которой совпадает со строкой преданно в параметре pszProvider. В этой папке находится ключ Image Path, в котором содержится путь библиотеки криптопровайдера.
Функция CryptAcquireContext() возвращает дескриптор контекста (сессии) по указателю phProv. При дальнейших вызовах всех Crypt* функций дескриптор контекста будет входным параметром. Дескриптор контекста определяет при вызовах других функций CrytoAPI 1.0 тот криптопровайдер, который был указан при инициализации контекста. Таким образом, вызов функции Crypt* перенаправляется в библиотеку найденную по имени при вызове CryptAcquireContext(), в самом начале работы с CrytoAPI 1.0. Собственно, все вызовы криптографических функций CrytoAPI 1.0 «обрамляются» вызовами двух функций — CryptAcquireContext() и CryptReleaseContext(), — открытие и закрытие сессии работы с криптопровайдером.
CryptoSPI регламентирует состав параметров вызова функций криптопровайдра, а также регламентирует некоторый стандартный (закрепленный) набор флагов и значений параметров вызова. Также регламентируется набор возвращаемых ошибок. Однако разработчикам разрешается добавлять собственные параметры и флаги вызовов. Есть также набор необязательных параметров и флагов, которые разрабатываемый криптопровайдер может или игнорировать или не поддерживать.
Для завершения описания функциональности криптопровайдера ниже приведены таблицы, описывающие внутренний интерфейс криптопровайдера CryptoSPI.
Таблица 6.2. – Функции инициализации и параметров криптопровайдера
Название | Описание |
CPAcquireContext() | Используется для создания дескриптора криптопровайдера с именем ключевого контейнера. |
CPReleaseContext() | Используется для удаления дескриптора криптопровайдера, созданного функцией CPAcquireContext(). |
CPGetProvParam() | Производит возвращение параметров криптопровайдера. |
CPSetProvParam() | Устанавливает параметры криптопровайдера. |
Таблица 6.3. ‑ Функции генерации и работы с ключами
Название | Описание |
CPGenKey() | Производит случайные криптографические ключи или парные (секретный/открытый) ключи. |
CPDestroyKey() | Удаляет ключ. После удаления ключ (дескриптор ключа) не может использоваться. |
CPDeriveKey() | Производит криптографические ключи сессии на основе значения хэш-функции, вычисленной по другим ключам, паролям или любым другим данным пользователя. |
CPDuplicateKey() | Создает копию заданного ключа, включая все его переменные, определяющие внутреннее состояние ключа (например, синхропосылки). |
CPExportKey() | Используется для экспорта криптографических ключей из ключевого контейнера криптопровайдера, сохраняя их в защищённом виде. |
CPGenRandom() | Используется для заполнения буфера случайными байтами. |
CPGetKeyParam() | Возвращает параметры ключа. |
CPGetUserKey() | Возвращает дескриптор одной из постоянных ключевых пар в ключевом контейнере. |
CPImportKey() | Используется для импорта криптографического ключа из ключевого блоба в контейнер криптопровайдера. |
CPSetKeyParam() | Устанавливает параметры ключа. |
|
|
Таблица 6.4. ‑ Функции шифрования/расшифрования данных
Название | Описание |
CPEncrypt() | Производит зашифрование данных. Одновременно может быть произведено их хэширование. |
CPDecrypt() | Расшифровывает данные, предварительно зашифрованные функцией CPEncrypt(). Одновременно может быть произведено хэширование данных. |
Таблица 6.5. ‑ Функции хэширования и ЭЦП
Название | Описание |
CPCreateHash() | Инициализирует дескриптор нового объекта функции хэширования потока данных. |
CPDestroyHash() | Разрушает объект функции хэширования. |
CPDuplicateHash() | Создает точную копию объекта функции хэширования, включая все его переменные, определяющие внутреннее состояние объекта функции хэширования. |
CPGetHashParam() | Возвращает параметры объекта функции хэширования и значение функции хэширования. |
CPHashData() | Передаёт данные указанному объекту функции хэширования. |
CPHashSessionKey() | Передаёт криптографический ключ указанному объекту функции хэширования. Это позволяет хэшировать ключи сессии без передачи ключа приложению. |
CPSetHashParam() | Устанавливает параметры объекта хэширования. |
CPSignHash() | Возвращает значение электронной цифровой подписи от значения функции хэширования. |
CPVerifySignature() | Осуществляет проверку цифровой подписи, соответствующей объекту функции хэширования. |