CryptoAPI • CryptoAPI - интерфейс программирования приложений, который обеспечивает разработчиков Windows-приложений стандартным набором функций для работы с криптопровайдером. • CryptoAPI Входит в состав операционной системы Windows. CryptoAPI • CryptoAPI – набор готовых определений криптографических функций, предоставляемых операционной системой Windows для использования во внешних программах. • Определение функции содержит: – Название функции – Параметры функции с указанием их типов данных – Тип данных возвращаемого значения • Определение функции также называют интерфейсом Криптопровайдер • Криптопровайдер содержит набор готовых криптографических функций, интерфейсы которых описаны в CryptoAPI. • Приложения вызывают функции CryptoAPI, а криптопровайдеры разрабатывают наполнение этих функций. • Существуют разные типы операций, и соответствующие им криптографические стандарты: – Шифрование – Хэширование – Цифровая подпись – Обмен ключами. • Каждый криптопровайдер реализует один или несколько криптографических стандартов. • В ОС Windows есть несколько встроенных криптопровайдеров. Разработчики могут создавать новые криптопровайдеры. Схема взаимодействия приложений и криптопровайдеров Приложение А Приложение В Приложение С CryptoAPI Операц. система Криптопровайдер 1 Криптопровайдер 2 Уровень приложений Системный уровень Криптопровайдер N Уровень криптопровайдера Криптопровайдер должен обеспечивать: • реализацию стандартного интерфейса криптопровайдера; • работу с ключами шифрования, специфичными для данного криптопровайдера; • невозможность вмешательства третьих лиц в схему работы алгоритмов. Группы функций CryptoAPI для работы с криптопровайдерами 1. функции подготовки контекста и получения параметров криптопровайдера; 2. функции генерации ключей и работы с ними; 3. функции шифрования/расшифровывания данных; 4. Функции хэширования и получения цифровой подписи данных. Функции подготовки контекста • Контекст – структура, содержащая служебные переменные для дальнейших операций. • CryptAcquireContext. Подготовка контекста криптопровайдера. • CryptContextAddRef. Создание ссылки на контекст. • CryptReleaseContext. Освобождение контекста криптопровайдера. • CryptGetProvParam. Получение различных параметров криптопровайдера. Функции работы с ключами • CryptGenKey. Создание ключа. • CryptDuplicateKey. Копирование ключа. • CryptGetUserKey. Получение приватного ключа текущего пользователя. • CryptDestroyKey. Удаление ключа. • CryptExportKey. Экспорт ключа для его передачи по каналам информации. • CryptImportKey. Получение из каналов информации значения ключа. Функции шифрования/расшифровывания • В функциях используются: – контекст криптопровайдера – сессионный ключ. (кратковременный) • CryptEncrypt. Шифрование данных. • CryptDecrypt. Расшифровывание данных. Функции хэширования и получения цифровой подписи • CryptCreateHash. Создание хэш-объекта. • CryptHashData. хэширование данных. • CryptGetHashParam получение значения сформированного хэша данных • CryptSetHashParam. Изменение параметров хэширования. • CryptDestroyHash. Удаление хэш-объекта. • CryptDuplicateHash. Копирование хэша. • CryptSignHash. Создание цифровой подписи хэша. • CryptVerifySignature Проверка цифровой подписи хэша. Microsoft Enhanced Cryptographic Provider (MS_ENHANCED_PROV) Создание контекста криптопровайдера HCRYPTPROV hProv; if(!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET)) { cout << “Ошибка при создании криптопровайдера” << endl; return; } //здесь что-то делаем //... CryptReleaseContext(hProv,0); Работа с ключами при шифровании //читаем публичный ключ удалённого пользователя if(::ReadFile(hKeyFile,&key,sizeof(RSAPubKey1024),&dwLen,NULL)) HCRYPTKEY hPubKey; //и импортируем его if(::CryptImportKey(hProv,(BYTE *)&key,sizeof(RSAPubKey1024),NULL,0,&hPubKey)) { return;} // что-то делаем … HCRYPTKEY hKey; //генерируем сессионный ключ для шифрования данных if(!::CryptGenKey(hProv, CALG_RC4,CRYPT_EXPORTABLE,&hKey)) { return; } EncFileHeader fh; dwLen=sizeof(RSA1024KeyExchBLOB); //экспортируем сессионный ключ, шифруя его на открытом ключе удалённого пользователя if(::CryptExportKey(hKey,hPubKey,SIMPLEBLOB,0,(BYTE *)&fh.kb,&dwLen)) Шифрование // Данные для шифрования char string[]="Test"; DWORD count=strlen(string); // Шифрование данных if (!CryptEncrypt(hKey, 0, true, 0, (BYTE*)string, &count, strlen(string))) {return;} // Тестовый вывод на экран std::cout << "Encrypted string: " << string << std::endl; Работа с ключами при расшифровании HCRYPTKEY hPrivKey; //достаем приватный ключ пользователя if(!::CryptGetUserKey(hProv,AT_KEYEXCHANGE,&hPrivKey)) {return;} //считываем зашифрованный сессионный ключ EncFileHeader fh; if(::ReadFile(hInFile,&fh,sizeof(fh),&dwLen,NULL)) {return;} HCRYPTKEY hKey; //импортируем сессионный ключ if(::CryptImportKey(hProv,(BYTE *)&fh.kb,sizeof(RSA1024KeyExchBLOB),hPrivKey,0,&hKey)) Расшифрование // Расшифровывание данных if(!CryptDecrypt(hKey, 0, true, 0, (BYTE*)string, &count)) { return; } std::cout << "Decryption completed" << std::endl; // Тестовый вывод на экран std::cout << "Decrypted string: " << string << std::endl; // Освобождение контекста локальных переменных CryptDestroyKey(hKey); CryptReleaseContext(hProv, 0); Назначение криптопровайдера, используемого по умолчанию • Открыть редактор реестра regedit • Перейти в раздел HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft \Cryptography \Defaults\Provider Types\Type 001 • Записать в ключ “Name” имя желаемого криптопровайдера. Например: «Microsoft Strong Cryptographic Provider» • Допустимые криптопровайдеры перечислены рядом, в разделе HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft \Cryptography \Defaults\Provider Литература Щербаков Л. Ю., Домашев А. В. Прикладная криптография. Использование и синтез криптографических интерфейсов • Есть примеры кода • В приложении 2 подробно описаны функции и их параметры