C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Передача ключей по сети или через файл в CryptoAPI, экспорт\импорт пары ключей
warlocklex
Отправлено: 21.12.2006, 21:36


Ученик-кочегар

Группа: Участник
Сообщений: 1



Не как не могу разобраться как передать ключ….пару ключей по сети.

На стороне сервера создает пару ключей:
CODE

// Получение хэндл криптопровайдера
if (!CryptAcquireContext(&hProv, NULL,MS_DEF_PROV,
   PROV_RSA_FULL,0))
{ShowMessage(IntToStr(g));
 return; }
// генерация сессионного ключа
if (!CryptGenKey(hProv,CALG_RC4,CRYPT_EXPORTABLE|CRYPT_ENCRYPT, &hSessionKey))
{
 ShowMessage("Error_CryptGenKey");  return;
}
// получение ключа для экспорта ключа шифрования
if (!CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hPublicKey)){
 ShowMessage("error_CryptGetUserKey");
 return;         }
countbk = 0;

if (!CryptExportKey(hSessionKey, hPublicKey,SIMPLEBLOB, 0, NULL, &countbk)){
ShowMessage("error_CryptExportKey1");
 return;     }
/*BYTE* */data = static_cast<BYTE*>(malloc(countbk));

ZeroMemory(data, count);

// экспорт ключа шифрования
if (!CryptExportKey(hSessionKey, hPublicKey,SIMPLEBLOB, 0, data, &countbk)){
  ShowMessage("error_CryptExportKey");
 return;}


на стороне клиента что то связанное с:
CODE

if(!CryptImportKey(hProv, data, countbk, hPublicKey, 0, &hNewKey)){
   ShowMessage(GetLastError());
   ShowMessage("clientError_Key's import");
   return;}


в одной программе всё работает — это понятно. Но по сети не получается: я передавал
и data(BYTE *pbData) и countbk(DWORD dwDataLen) и hPublicKey(HCRYPTKEY hImpKey) .На разных машинах создаются разные провайдеры hProv(HCRYPTPROV hProv).

Или я не туда пошел.Подскажите!!!!ПЖАЛУЙСТА!! а то «у меня уже фляга брызжет».

Или ссылку где популярно обЪеснино или хотя бы намек
vvoid
Отправлено: 22.12.2006, 12:47


Машинист паровоза

Группа: Участник
Сообщений: 171



Приветствую.

Смотри.
Суть задачи: произвести обмен сессионным ключём (ключём для алгоритма симметричного шифрования RC4). Поскольку это секретный ключ, никто не даст тебе прямой возможности експортонуть его в открытом виде, поскольку это не безопасно. Для того, чтобы обезопасить обмен подобными ключами используется асимметричная криптография (алгоритмы RSA, DSA, ECDSA и т.д.) Их отличие в том, что для шифрования используется один ключ (открытый — общедоступный), для расшифрования другой (приватный — секретный). Таким образом, кто угодно может зашифровать сообщение с использованием открытого ключа, но расшифровать его может только владелец секретного ключа.

Итак, а теперь схема обмена ключами:
(пусть А — сторона, которая хочет передать сессионный ключ, а В — сторона, которая должна его принять)

1. Сторона А генерирует (CryptGenKey(...,&SessionKeyHandle)) секретный сессионный ключ.

2. Сторона В (!) генерирует пару асимметричных ключей (CryptGenKey с флагом AT_KEYEXCHANGE) или каким либо другим образом (CryptGetUserKey) получает хендл ExchangeKeyHandle (на самом деле это хендл не на один ключ а на пару секретный-открытый);
экспортироует открытый (PUBLIC) ключ (CryptExportKey(ExchangeKeyHandle,xxx,PUBLICKEYBLOB,...)), сохранаяет результат, предположим, в файл, и отсылает его по обычному каналу стороне А.

3. Сторона А, приняв (CryptImportKey(xxx,xxx,xxx,0,xxx,&ExchangeKeyHandle)) открытый ключ, зашифровывает (экспортирует) с ЕГО помощью СЕССИОННЫЙ ключ (CryptExportKey(SessionKeyHandle,ExchangeKeyHandle,SIMPLEBLOB,...)). Результат експорта отсылается стороне В.

4. Сторона В, приняв сессионный ключ, зашифрованный на её открытом ключе, расшифровывает его при помощи своего секретного ключа (CryptImportKey(xxx,xxx,xxx,ExchangeKeyHandle,CRYPT_EXPORTABLE,&SecretKeyHandle))

И только после этого обе стороны будут иметь одинаковый ключ для симметричного алгоритма шифрования.

Надеюсь не сильно мутороно написал и не сильно напутал с функциями и параметрами. Но идею вроде бы изложил.
Удачи.

Отредактировано vvoid — 22.12.2006, 13:01

Вернуться в Вопросы программирования в C++Builder