Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
PoIRoCSaN_Lab_1.3(wincrypto).doc
Скачиваний:
6
Добавлен:
18.02.2023
Размер:
259.58 Кб
Скачать

Экспорт сессионных ключей

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

Базовая функция экспорта ключей имеет следующее описание:

BOOL CryptExportKey(HCRYPTKEY hKey,

HCRYPTKEY hExpKey,

DWORD dwBlobType,

DWORD dwFlags,

BYTE* pdData,

DWORD* pdwDataLen);

Первым параметром данной функции передается хендл ключа, который будет экспортирован. Фактически, экспорт ключа можно представить как отдельную операцию шифрования ключа. Следовательно, для такой операции необходим еще один ключ шифрования. Обычно в Crypto API сессионный ключ шифруют с помощью асимметричного алгоритма. Параметр hExpKey в большинстве случаев инициализируют контекстом публичного ключа получателя. Параметр dwBlobType определяет формат получаемого блока экспорта. Возможно, скажем, указать, что экспорту будет подлежать только лишь публичный ключ. В этом случае параметр hExpKey должен быть равен 0 (шифрование публичного ключа не нужно) и на выходе функции получается простое значение публичного ключа. Для такого случая параметр dwBlobType должен быть равен PUBLICKEYBLOB. Обычно же, при экспорте сессионного ключа используется значение SIMPLEBLOB. Остальные значения данного параметра достаточно специфичны и применяются редко. Параметры pbData и pdwDataLen указывают на массив, выделенный для получения экспортируемого ключа, и на его размер.

СОВЕТ

Хотелось бы также обратить внимание читателя на достаточно важный момент: иногда для обмена ключами используются несколько более сложные схемы, чем просто шифрование данных сессионного ключа публичным ключем. Примером подобной усложненной схемы обмена может служить алгоритм обмена ключами по методу Диффи-Хеллмана. В данном алгоритме используются оба публичных ключа – как отправителя, так и получателя. Более подробную информацию о данном алгоритме читатель может найти в специализированной литературе.

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

HCRYPTPROV hProv;

HCRYPTKEY hKey, hPublicKey, hNewKey;

// Инициализация контекста криптопровайдера (с указанием имени

// контейнера ключей)

if (!CryptAcquireContext(&hProv, "{EB57ED8A-CCCC-4bf5-8659-9DF2F05F24AD}",

NULL, PROV_RSA_FULL, 0))

return;

std::cout << "Cryptographic provider initialized" << std::endl;

// Генерация ключа для тестирования

if (!CryptGenKey(hProv, CALG_RC4,

CRYPT_EXPORTABLE | CRYPT_ENCRYPT | CRYPT_DECRYPT, &hKey))

return;

std::cout << "Session key generated" << std::endl;

// Получение ключа для экспорта ключа шифрования

if (!CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hPublicKey))

return;

std::cout << "Public key is received" << std::endl;

count = 0;

// Получение размера массива, используемого для экспорта ключа

if (!CryptExportKey(hKey, hPublicKey, SIMPLEBLOB, 0, NULL, &count))

return;

// Инициализация массива, используемого для экспорта ключа

BYTE* data = static_cast<BYTE*>(malloc(count));

ZeroMemory(data, count);

// Экспорт ключа шифрования

if (!CryptExportKey(hKey, hPublicKey, SIMPLEBLOB, 0, data, &count))

return;

std::cout << "Key's export completed" << std::endl;