Цифровая подпись в проектах на CryptoAPI (Лабораторная работа № 3)

Страницы работы

Содержание работы

Лабораторная работа № 3.

Цифровая подпись в проектах на CryptoAPI.

Цель: Научиться создавать ключевую пару (открытый и закрытый ключи) для цифровой подписи, манипулировать ключами (сохранять в файл, извлекать из файла, импортировать и экспортировать в хранилище ключей), подписывать произвольные документы (файлы) и проверять подпись под ними.

Задача: Написать программу для подписи и проверки подписи электронных документов на выбранных пользователем ключах электронной подписи и на выбранном алгоритме. Предусмотреть в программе генерацию ключевой пары в файл.

Отчёт: Отчёт по лабораторной работе должен содержать:

1.  цель работы;

2.  постановка задачу;

3.  исходный текст программы.

Краткая теория

Как и в случае симметричной криптографии, для использования функций подписи и её проверки, необходимо получить контекст провайдера с помощью уже известной функции CryptAcquireContext и после работы освободить его с помощью CryptReleaseContext.

После инициализации можно приступать к созданию ключей подписи, манипулированию ими и применению их для подписи и проверки.

Создание ключей

Для создания ключей используется функция CryptGenKey, которая имеет следующий прототип:

BOOL[1] WINAPI CryptGenKey(

  HCRYPTPROV hProv,

  ALG_ID Algid,

  DWORD dwFlags,

  HCRYPTKEY *phKey

);

Указатель на переменную, которая примет идентификатор объекта «ключ», передаётся последним параметром. Первым параметром (hProv) передаётся идентификатор контекста провайдера, который мы уже инициализировали и который имеет алгоритм Algid среди поддерживаемых. Algid – это идентификатор криптографического алгоритма, для которого, собственно говоря, и создаются ключи. Он может (и должен) быть получен путём перечисления всех поддерживаемых алгоритмов у провайдера. Это поле aiAlgid в структуре PROV_ENUMALGS при перечислении алгоритмов с помощью функции CryptGetProvParam с параметром PP_ENUMALGS. Algid, однако, может принимать константные значения CALG_RSA_SIGN и CALG_DSS_SIGN исключительно в отладочных целях на этапе проектирования программы. dwFlags – это флаги создания ключей. В старшем слове этого параметра передаётся размер ключа (или нулевое значение в случае использования размера по умолчанию), а в младшем передаются флаги типа ключа. Их значения можно посмотреть в MSDN. Обычно здесь передаётся флаг CRYPT_EXPORTABLE, чтобы иметь возможность экспортировать ключ.

Ключ создаётся внутри защищённого пользовательского контейнера (подробнее об этом смотри MSDN). Например, в случае использования провайдера смарт-карт, ключ будет создан на текущей, вставленной в привод смарт-карте. В контейнер ключ может быть импортирован, а также экспортирован из него (см. далее по тексту).

После создания и использования ключа, его дескриптор должен быть уничтожен функцией CryptDestroyKey;

BOOL WINAPI CryptDestroyKey(

  HCRYPTKEY hKey

);

Например:

C++

void genKeyPair(HCRYPTPROV prov)

{

  HCRYPTKEY key;

  const int KEY_LENGTH = 1024;

  ::CryptGenKey(

    prov, CALG_RSA_SIGN, MAKELONG(CRYPT_EXPORTABLE, KEY_LENGTH), &key

  );

  // ... Используем ключ, например, сохраняем в файл ...

  ::CryptDestroyKey(key);

}

Delphi

procedure GenKeyPair(prov: HCRYPTPROV);

const

  KEY_LENGTH = 1024;

var

  key : HCRYPTKEY;

begin

  CryptGenKey(

    prov, CALG_RSA_SIGN, MAKELONG(CRYPT_EXPORTABLE, KEY_LENGTH), @key

  );

  { ... Используем ключ, например, сохраняем в файл ... }

  CryptDestroyKey(key);

end;

Экспортирование и импортирование ключей

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

BOOL WINAPI CryptExportKey(

  HCRYPTKEY hKey,

  HCRYPTKEY hExpKey,

  DWORD dwBlobType,

  DWORD dwFlags,

  BYTE *pbData,

  DWORD *pdwDataLen

);

Полученный после вызова функции CryptGenKey идентификатор ключа передайте первым параметром. Второй параметр — это ключ пользователя, которому мы хотим передать наш ключ. Это может быть, например общий симметричный ключ, который есть и у нас и у него, или его открытый ключ шифрования. На этом ключе будет зашифрован блоб ключа (BLOB — Binary Large OBject, большой двоичный объект, «блоб» (тип данных)) в пятом параметре. Также можно зашифровать его на пароле. Воспользоваться ключом смогут только знающие пароль. Если передать сюда нулевое значение, блоб ключа не будет зашифровываться.

Похожие материалы

Информация о работе