Методы криптографической защиты информации Windows

Рассмотрим пример создания ключевых пар при помощи формы. В поле "Контейнер" можно указать имя контейнера ключей; если оставить это поле пустым, будет использован контейнер по умолчанию. Назначение остальных элементов управления должно быть интуитивно понятным. После генерации ключа в memo-поле выводится отчет о его параметрах. Для этого используется функция CryptGetKeyParam (ключ, параметр, буфер, размер, флаги). Чтобы получить информацию о требуемом параметре, нужно через второй аргумент функции передать соответствующую константу: KP_ALGID - идентификатор алгоритма, KP_KEYLEN - размер ключа, и т. д. Ниже приведен текст процедуры генерации ключей без операторов обработки ошибок:

procedure TGenerateForm.OKBtnClick(Sender: TObject);
var
 cont: PChar;
 err: string;
 hProv: HCRYPTPROV;
 KeyExchKey, SignKey: HCRYPTKEY;
 flag, keyLen: DWORD;
begin
 {если ни один ключ не выбран - выход}
 if not (KEKCheckBox.Checked or SKCheckBox.Checked) then
  exit;
 {"считываем" имя контейнера}
 if length(ContainerEdit.Text) = 0 then
  cont := nil
 else
 begin
  err := ContainerEdit.Text;
  cont := StrAlloc(length(err) + 1);
  StrPCopy(cont, err);
 end;
 CryptAcquireContext(@hProv, cont, nil, PROV_RSA_FULL, 0);
 {генерация ключа обмена ключами (Key Exchange Key)}
 if KEKCheckBox.Checked then
 begin
  {"считываем" длину ключа и помещаем ее в
  старшее слово параметра ФЛАГИ}

  keyLen := strtoint(KeyExchLenEdit.text);
  flag := keyLen shl 16;
  if not CryptGenKey(hProv, AT_KEYEXCHANGE, flag, @KeyExchKey) then
  begin
  јобработка ошибокј
  end
  else
  begin
  ReportMemo.Lines.Add('');
  ReportMemo.Lines.Add('Создан ключ обмена ключами:');
  flag := 4;
  if not CryptGetKeyParam(KeyExchKey, KP_KEYLEN, @keyLen, @flag, 0) then
  begin
  јобработка ошибокј
  end
  else
  ReportMemo.Lines.Add(' длина ключа - ' + inttostr(keyLen));
  flag := 4;
  if not CryptGetKeyParam(KeyExchKey, KP_ALGID, @keyLen, @flag, 0) then
  begin
  јобработка ошибокј
  end
  else
  ReportMemo.Lines.Add(' алгоритм - ' + algIDtostr(keyLen));
  {функция algIDtostr здесь не приводится. Она состоит из единственного
  оператора case, отображающего целый идентификатор алгоритма в строку}

  end;
 end;
 {генерация ключа подписи (Signature Key)}
 if SKCheckBox.Checked then
 begin
  јвыполняется аналогично генерации ключа обмена ключамиј
 end;
 CryptReleaseContext(hProv, 0);
end;

Обмен ключами
Теперь мы располагаем набором ключей, однако все они останутся мертвым грузом, до тех пор пока мы не получим возможности обмена с другими пользователями открытыми ключами. Для этого необходимо извлечь их из базы данных ключей и записать в файл, который можно будет передать своим корреспондентам. При экспорте данные ключа сохраняются в одном из трех возможных форматов:
PUBLICKEYBLOB - используется для сохранения открытых ключей. Поскольку открытые ключи не являются секретными, они сохраняются в незашифрованном виде;
PRIVATEKEYBLOB - используется для сохранения ключевой пары целиком (открытого и закрытого ключей). Эти данные являются в высшей степени секретными, поэтому сохраняются в зашифрованном виде, причем для шифрования используется сеансовый ключ (и, соответственно, симметричный алгоритм);
SIMPLEBLOB - используется для сохранения сеансовых ключей. Для обеспечения секретности данные ключа шифруются с использованием открытого ключа получателя сообщения.
Экспорт ключей в CryptoAPI выполняется функцией CryptExportKey (экспортируемый ключ, ключ адресата, формат, флаги, буфер, размер буфера):
экспортируемый ключ - дескриптор нужного ключа;
ключ адресата - в случае сохранения открытого ключа должен быть равен нулю (данные не шифруются);
формат - указывается один из возможных форматов экспорта (PUBLICKEYBLOB, PRIVATEKEYBLOB, SIMPLEBLOB);
флаги - зарезервирован на будущее (должен быть равен нулю);
буфер - содержит адрес буфера, в который будет записан ключевой BLOB (Binary Large OBject - большой двоичный объект);
размер буфера - при вызове функции в этой переменной должен находиться доступный размер буфера, а по окончании работы в нее записывается количество экспортируемых данных. Если размер буфера заранее не известен, то функцию нужно вызвать с параметром буфер, равным пустому указателю, тогда размер буфера будет вычислен и занесен в переменную размер буфера.
Экспорт ключевой пары целиком, включая и закрытый ключ, может понадобиться для того, чтобы иметь возможность подписывать документы на различных компьютерах (например, дома и на работе), или для сохранения страховочной копии. В этом случае нужно создать ключ шифрования на основании пароля (см. "К+П", № 10/2002) и передать дескриптор этого ключа в качестве второго параметра функции CryptExportKey.
Запросить у криптопровайдера дескриптор самого' экспортируемого ключа позволяет функция CryptGetUserKey (провайдер, описание ключа, дескриптор ключа). Описание ключа - это либо AT_KEYEXCHANGE, либо AT_SIGNATURE.
Экспорт асимметричных ключей во всем возможном многообразии можно осуществить при помощи формы.

Отправить комментарий

Проверка
Антиспам проверка
Image CAPTCHA
...