Открыть сервис

BCryptGenerateKeyPair

BCryptGenerateKeyPair — это функция из набора криптографических примитивов (Cryptographic Primitives) Windows, входящая в состав интерфейса программирования приложений (API) Cryptography Next Generation (CNG). Она предназначена для генерации пары асимметричных ключей (открытого и закрытого) в контексте заданного алгоритма, используя для этого предварительно созданный и инициализированный хэндл ключевого хранилища (BCRYPT_KEY_HANDLE). Функция является частью низкоуровневого API, предоставляющего прямой доступ к криптографическим операциям без использования промежуточных библиотек высокого уровня, таких как CryptoAPI.

Назначение и контекст использования

Функция BCryptGenerateKeyPair применяется в сценариях, требующих создания асимметричных ключей для последующего выполнения операций шифрования, цифровой подписи, обмена ключами или аутентификации. В отличие от симметричных алгоритмов, где один и тот же ключ используется для шифрования и расшифрования, асимметричные алгоритмы (например, RSA, ECDSA, DSA) оперируют парой ключей: открытый ключ распространяется открыто, а закрытый хранится в секрете. Генерация такой пары выполняется однократно для каждого сеанса работы с ключами и является обязательным этапом перед экспортом открытого ключа или выполнением криптографических операций.

Синтаксис и параметры

Функция объявлена в заголовочном файле bcrypt.h и имеет следующий прототип на языке C:

``c NTSTATUS BCryptGenerateKeyPair( BCRYPT_ALG_HANDLE hAlgorithm, BCRYPT_KEY_HANDLE *phKey, ULONG dwLength, ULONG dwFlags ); ``

Параметры

  • hAlgorithm — хэндл алгоритма, полученный с помощью функции BCryptOpenAlgorithmProvider. Этот хэндл должен быть открыт для алгоритма, поддерживающего асимметричные ключи (например, BCRYPT_RSA_ALGORITHM, BCRYPT_ECDSA_P256_ALGORITHM, BCRYPT_DSA_ALGORITHM). Хэндл должен быть открыт с флагом BCRYPT_ALG_HANDLE_HMAC_FLAG только в случае, если алгоритм поддерживает HMAC, что для асимметричных алгоритмов нехарактерно.
  • phKeyуказатель на переменную типа BCRYPT_KEY_HANDLE, в которую после успешного вызова будет записан хэндл созданной пары ключей. Этот хэндл используется в последующих вызовах функций для работы с ключом (например, BCryptExportKey, BCryptSignHash, BCryptEncrypt).
  • dwLength — размер ключа в битах. Для алгоритмов с фиксированным размером ключа (например, для ECDSA на кривой P-256 размер всегда 256 бит) этот параметр должен быть равен соответствующему значению. Для алгоритмов с переменным размером ключа (например, RSA) можно указать любое значение из поддерживаемого диапазона (обычно от 512 до 16384 бит, с шагом 64 бита). Если указать 0, функция использует размер по умолчанию для данного алгоритма.
  • dwFlags — флаги, изменяющие поведение функции. В текущей реализации Windows (по состоянию на 2024 год) единственным определённым флагом является BCRYPT_NO_KEY_VALIDATION, который отключает проверку сгенерированного ключа на соответствие стандартам безопасности (например, проверку на простоту чисел для RSA). Использование этого флага не рекомендуется в production-среде, так как может привести к созданию криптографически слабых ключей. Для обычного использования следует передавать 0.

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

Функция возвращает код состояния типа NTSTATUS. Успешное выполнение возвращает STATUS_SUCCESS. В случае ошибки возвращается соответствующий код ошибки, например:

  • STATUS_INVALID_PARAMETER — один из параметров имеет некорректное значение (например, dwLength выходит за пределы поддерживаемого диапазона).
  • STATUS_NOT_SUPPORTED — алгоритм, указанный в hAlgorithm, не поддерживает генерацию пар ключей (например, если это симметричный алгоритм).
  • STATUS_INVALID_HANDLE — хэндл алгоритма недействителен или закрыт.

Порядок вызова

Для корректной работы с функцией BCryptGenerateKeyPair необходимо соблюдать определённую последовательность вызовов:

  1. Открытие провайдера алгоритма: вызов BCryptOpenAlgorithmProvider с указанием идентификатора алгоритма (например, BCRYPT_RSA_ALGORITHM) и флагами (обычно 0 или BCRYPT_ALG_HANDLE_HMAC_FLAG для алгоритмов, поддерживающих HMAC, хотя для асимметричных алгоритмов это не нужно).
  2. Генерация пары ключей: вызов BCryptGenerateKeyPair с полученным хэндлом алгоритма, указателем на переменную для хэндла ключа, размером ключа в битах и флагами (обычно 0).
  3. Завершение генерации: вызов функции BCryptFinalizeKeyPair, которая завершает процесс генерации и делает ключ готовым к использованию. Без этого вызова ключ не может быть использован для криптографических операций.
  4. Использование ключа: после вызова BCryptFinalizeKeyPair можно экспортировать открытый ключ (с помощью BCryptExportKey), выполнять подпись (с помощью BCryptSignHash) или шифрование (с помощью BCryptEncrypt).
  5. Освобождение ресурсов: после завершения работы с ключом необходимо вызвать BCryptDestroyKey для освобождения памяти и закрытия хэндла. Также следует закрыть хэндл алгоритма с помощью BCryptCloseAlgorithmProvider.

Пример использования (псевдокод)

```c BCRYPT_ALG_HANDLE hAlg = NULL; BCRYPT_KEY_HANDLE hKey = NULL; NTSTATUS status;

// 1. Открываем провайдер RSA status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RSA_ALGORITHM, NULL, 0); if (!NT_SUCCESS(status)) { // обработка ошибки }

// 2. Генерируем пару ключей RSA длиной 2048 бит status = BCryptGenerateKeyPair(hAlg, &hKey, 2048, 0); if (!NT_SUCCESS(status)) { BCryptCloseAlgorithmProvider(hAlg, 0); // обработка ошибки }

// 3. Завершаем генерацию status = BCryptFinalizeKeyPair(hKey, 0); if (!NT_SUCCESS(status)) { BCryptDestroyKey(hKey); BCryptCloseAlgorithmProvider(hAlg, 0); // обработка ошибки }

// 4. Используем ключ (например, экспортируем открытый ключ) // ...

// 5. Освобождаем ресурсы BCryptDestroyKey(hKey); BCryptCloseAlgorithmProvider(hAlg, 0); ```

Особенности и ограничения

  • Поддерживаемые алгоритмы: функция работает только с асимметричными алгоритмами. Для симметричных алгоритмов (например, AES, 3DES) используется функция BCryptGenerateSymmetricKey.
  • Состояние ключа: после вызова BCryptGenerateKeyPair ключ находится в состоянии «незавершённого» (unfinalized). В этом состоянии нельзя выполнять криптографические операции — необходимо сначала вызвать BCryptFinalizeKeyPair. Исключение составляет экспорт открытого ключа: некоторые реализации позволяют экспортировать открытый ключ до финализации, но это не гарантируется документацией.
  • Потокобезопасность: функция не является потокобезопасной. Если несколько потоков одновременно вызывают BCryptGenerateKeyPair с одним и тем же хэндлом алгоритма, поведение не определено. Рекомендуется создавать отдельный хэндл алгоритма для каждого потока или использовать синхронизацию.
  • Производительность: генерация асимметричных ключей, особенно для больших размеров (например, RSA-4096), может занимать значительное время (от нескольких секунд до десятков секунд на слабых устройствах). Это связано с необходимостью нахождения больших простых чисел и выполнения тестов на простоту.
  • Поддержка в Windows: функция доступна начиная с Windows Vista и Windows Server 2008. В более ранних версиях Windows (XP, Server 2003) используется устаревший CryptoAPI.

Сравнение с альтернативами

В экосистеме Windows существуют и другие способы генерации асимметричных ключей:

  • CryptoAPI (функция CryptGenKey): более старый API, который также позволяет генерировать ключи, но имеет ограниченную поддержку современных алгоритмов (например, ECDSA) и менее гибкий интерфейс.
  • .NET Framework (класс RSACryptoServiceProvider): высокоуровневая обёртка, которая внутри использует либо CryptoAPI, либо CNG в зависимости от версии .NET и операционной системы.
  • OpenSSL: кроссплатформенная библиотека, которая может использоваться в Windows, но не является частью операционной системы.

BCryptGenerateKeyPair является предпочтительным выбором для приложений, написанных на C/C++ и требующих прямого доступа к криптографическим функциям Windows с поддержкой современных алгоритмов.

Источники

  • Microsoft Docs. «BCryptGenerateKeyPair function (bcrypt.h)». Windows App Development.
  • Microsoft Docs. «Cryptography Next Generation (CNG)». Windows App Development.
  • Microsoft Docs. «BCryptFinalizeKeyPair function (bcrypt.h)». Windows App Development.
  • Microsoft Docs. «BCryptOpenAlgorithmProvider function (bcrypt.h)». Windows App Development.

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →