Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Тема 7 Создание, хранение и распространение криптографических ключей с помощью CryptoApi.




Большинство криптопровайдеров не создают автоматически пары ключей асимметричного шифрования при создании контейнера ключей. Для создания пар ключей асимметричного шифрования должна использоваться следующая функция CryptoAPI версии 1. 0:

BOOL CryptGenKey(HCRYPTPROV hProv, ALGJD Algid, DWORD dwFlags, HCRYPTKEY *phKey); /* создание в контейнере ключей с дескриптором hProv пары ключей ЭЦП (Algid=AT_SIGNATURE) или обмена сеансовыми ключами (Algid=AT_KEYEXCHANGE) и запись дескриптора открытого ключа созданной пары в *phKey; если закрытый ключ созданной пары должен иметь возможность экспорта из CSP, то dwFlags=CRYPT_EXPORTABLE (открытые ключи всегда являются экспортируемыми) */

Получение дескриптора открытого ключа *phUserKey из соответствующего контейнера ключей hProv возможно с помощью следующей функции:

BOOL CryptGetUserKey(HCRYPTPROV hProv, DWORD dwKeySpec, HCRYPTKEY *phUserKey); /* параметр dwKeySpec определяет тип запрашиваемого ключаобмена (AT_KEYEXCH AN GE) или ЭЦП (AT_SIGNATURE) */

Если функция CryptGetUserKey возвращает FALSE с кодом ошибки NTENOKEY, то запрашиваемый открытый ключ в контейнере ключей криптопровайдера с дескриптором hProv не существует и соответствующая пара ключей асимметричного шифрования (для обмена сеансовыми ключами или ЭЦП) должна быть создана с помощью функции CryptGenKey.

Для создания сеансового ключа также может использоваться функция CryptGenKey со значением параметра Algid, равным коду алгоритма используемого в приложении симметричного шифрования (CALGDES, CALGRC2, CALG3DES, CALG_ RC4 или др. ). Значение параметра dwFlags может быть объединением следующих флагов: CRYPT CREATE SALT (использование случайного значения для модификации ключа шифрования), CRYPT EXPORTABLE (сеансовый ключ может экспортироваться из CSP) и др.

При создании ключа может быть задана его длина, отличающаяся от длины по умолчанию. В этом случае параметр dwFlags при вызове функции CryptGenKey должен в комбинации с другими допустимыми флагами содержать значение типа DWORD, старшие 16 бит которого содержат требуемую длину ключа (например, для задания длины ключа ЭЦП 2048 бит нужно указать значение 0x08000000).

Экспорт криптографического ключа заключается в его получении внутри специального блока данных {блоба, от Bit Large OBject — BLOB) в открытом (тип блоба PUBLICKEYBLOB, предназначен для экспорта открытых ключей асимметричного шифрования) или зашифрованном (типы блоба SIMPLEBLOB для экспорта сеансовых ключей или PRIVATEKEYBLOB для экспорта закрытого и открытого ключей асимметричного шифрования). Ключом шифрования закрытого ключа при его экспорте должен быть специальный сеансовый ключ, обычно генерируемый на основе парольной фразы. Ключом шифрования экспортируемого сеансового ключа является открытый ключ получателя блоба с сеансовым ключом (т. е. лица с правами расшифрования зашифрованных на этом сеансовом ключе данных). Для экспорта и импорта ключей шифрования предназначены следующие функции Crypto API:

BOOL CryptExportKey(HCRYPTKEY hKey, HCRYPTKEY h Exp Key, DWORD dwBlobType, DWORD dwFlags, BYTE *pbData, DWORD *pdwDataLen); /* экспорт криптографического ключа с дескриптором hKey, зашифрованного с помощью ключа с дескриптором hExpKey, в блобе *pbData длиной *pdwDataLen типа dwBlobType; при успешном завершении в *pdwDataLen помещается фактическая длина блоба */

BOOL CryptImportKey(HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey); /* расшифрование криптографического ключа из блоба *pbData длиной dwDataLen с помощью ключа с дескриптором hPubKey и импорт восстановленного ключа в контейнер ключей hProv; при успешном завершении в *phKey помещается дескриптор импортированного ключа */

Расшифрование импортируемого сеансового ключа выполняется с помощью закрытого ключа получателя блоба, а импортируемого закрытого ключа — с помощью специального сеансового ключа.

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

BOOL CryptCreateHash(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH *phHash);

/* создание в криптопровайдере с дескриптором hProv пустого хеш-значения с дескриптором *phHash (в Algid, должен содержаться код алгоритма хеширования — CALG_MD2, CALG_MD4, CALG_MD5 или CALG_SHA), параметры hKey и dwFlags не используются и должны быть равны нулю */

BOOL CryptHashData(HCRYPTHASH hHash, CONST BYTE *pbData, DWORD dwDataLen, DWORD dwFlags); /* добавление к хеш-значению с дескриптором hHash данных (например, парольной фразы) из буфера *pbData длиной dwDataLen; параметр dwFlags не используется и должен быть равен нулю */

BOOL CryptDeriveKey(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTHASH hBaseData, DWORD dwFlags, HCRYPTKEY *phKey); /* создание сеансового ключа с дескриптором *phKey

из хеш-значения с дескриптором hBaseData; значения параметров Algid (код алгоритма шифрования) и dwFlags (флаги) могут быть такими же, как при вызове функции CryptGenKey */

После вызова функции Crypt De rive Key в используемое ею хеш-значение не могут быть добавлены новые данные. После завершения работы с хеш-значениями и ключами шифрования их дескрипторы должны быть разрушены (занимаемая ими оперативная память освобождена) в приложении с помощью следующих функций:

BOOL CryptDestroyKey(HCRYPTKEY hKey); /* разрушение дескриптора ключа шифрования hKey */

BOOL CryptDestroyHash(HCRYPTHASH hHash); /* разрушение дескриптора хеш-значения hHash */

Для изменения режима симметричного блочного шифрования используется функция CryptSetKeyParam:

BOOL CryptSetKeyParam (HCRYPTKEY hKey, DWORD dwParam, BYTE *pbData, DWORD dwFlags); /* установка режима шифрования для сеансового ключа с дескриптором hKey: dwParam=KP_MODE, pbData указывает на переменную типа DWORD (unsigned long), в которой записан код устанавливаемого режима, dwFlags=0 */

По умолчанию режим шифрования устанавливается в CRYPT_MODE_ СВС (шифрование в режиме сцепления блоков шифра). Функция CryptSetKeyParam может также применяться и для установки других параметров шифрования:

  • • использование вектора инициализации (синхропосылки) — dwParam=KP_IV и буфер *pbData содержит значение вектора инициализации;
  • • использование случайных значений для модификации ключа шифрования — dwParam=KP_SALT и буфер *pbData содержит случайное значение;
  • • размер порции данных для режимов шифрования с обратной связью CFB или OFB — dwParam=KP_MODE_BITS и буфер *pbData содержит размер порции данных (для встроенных в Windows криптопровайдеров Microsoft это значение по умолчанию равно 8);
  • • дополнительные ограничения на использование сеансового ключа — dwParam=KP_PERMISSIONS и буфер *pbData содержат комбинацию флагов CRYPTENCRYPT (разрешено шифрование на этом ключе), CRYPT DECRYPT (разрешено расшифрование с помощью этого ключа), CRYPT EXPORT (ключ может экспортироваться из CSP), CRYPT_READ (параметры ключа могут быть прочитаны), CRYPT WRITE (параметры ключа могут быть изменены), CRYPT MAC (ключ может использоваться для вычисления кода аутентификации сообщений); встроенные в Windows криптопровайдеры поддерживают только флаг CRYPT_ EXPORT.

Рассмотрим пример создания ключа шифрования файла на основе введенной парольной фразы в программе на языке C++, созданной в системе программирования Microsoft Visual C++. Парольная фраза вводится с помощью диалогового окна (рис. 3. 2), которому в приложении соответствует объект Dialog6. С текстовым редактором для ввода пароля в классе этого объекта связано строковое поле m_Editl.

 

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...