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

Void *md_data;

} /* EVP_MD_CTX */;

Заполнение контекста выполняется при помощи функции EVP_DigestInit(). В параметрах этой функции передаются указатели на контекст для вычисления хэша и на структуру, содержащую адреса функций алгоритма хэширования:

EVP_DigestInit(EVP_MD_CTX * ctx, EVP_MD * md)

Функция копирует структуру "EVP_MD * md" в контекст дайджеста путем приравнивания соответствующих указателей (см. файл crypto/evp/digest.c исходных текстов библиотеки):

ctx->digest = md;

Заполнив контекст, мы получаем возможность вызывать библиотечные функции для вычисления хэша, используя адреса, которые сохранены в структуре digest-контекста. Вычисление хэша выполняет функция EVP_DigestUpdate(), функция EVP_DigestFinal() копирует вычисленный хэш из контекста дайджеста в выходной буфер:

Int evp_DigestUpdate(evp_md_ctx *ctx, const void *d, unsigned int cnt);

Int evp_DigestFinal(evp_md_ctx *ctx, unsigned char *md, unsigned int *s);

Параметры функции EVP_DigestUpdate - указатель на контекст для вычисления хэша ctx, буфер d для хранения промежуточного результата вычисления и размер этого буфера cnt. Функция EVP_DigestFinal сохраняет размер вычисленного хэша в последнем параметре *s.

По завершении работы контекст для вычисления хэша очищается при помощи функции EVP_MD_CTX_cleanup().

Листинг 3 демонстрирует порядок использования высокоуровневых функций библиотеки для вычисления хэша файла по алгоритму MD5.

Листинг 3. Вычисление MD5-хэша файла с использованием высокоуровневых функций библиотеки

#include <openssl/md5.h>

#include <openssl/evp.h>

#define BUFSIZE (1025*16)

Void main(int argc, char **argv)

{

EVP_MD_CTX mdctx; /* контекст для вычисления хэша */

const EVP_MD * md; /* структура с адресами функций алгоритма */

unsigned char md_value[EVP_MAX_MD_SIZE];

Int md_len; /* размер вычисленного хэша */

/* В командной строке передаем имя файла, для которого вычисляется хэш */

int inf = open(argv[1], O_RDWR);

/* Добавляем алгоритмы хэширования во внутреннюю таблицу библиотеки */

OpenSSL_add_all_digests();

/* Получаем адреса функций алгоритма MD5 и инициализируем контекст для вычисления хэша */

md = EVP_get_digestbyname("md5");

EVP_DigestInit(&mdctx, md);

/* Вычисляем хэш */

for(;;) {

i = read(inf, buf, BUFSIZE);

if(i <= 0) break;

EVP_DigestUpdate(&mdctx, buf, (unsigned long)i);

}

/* Копируем вычисленный хэш в выходной буфер. Размер хэша сохраняем в переменной md_len */

EVP_DigestFinal(&mdctx, md_value, &md_len);

/* Очищаем контекст */

EVP_MD_CTX_cleanup(&mdctx);

/* Отобразим результат */

for(i = 0; i < md_len; i++) printf("%02x", md_value[i]);

}

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

Симметричные алгоритмы шифрования

Целью шифрования информации является предотвращение угрозы нарушения ее конфиденциальности, т.е. несанкционированное ознакомление с ней. Алгоритмы шифрования можно разделить на две основные категории:

n симметричное шифрование;

n ассиметричное шифрование.

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

Библиотека поддерживает большое количество симметричных алгоритмов. Некоторые из них мы сейчас рассмотрим, и начнем с самого знаменитого - с DES.

Алгоритм DES

Алгоритм DES (Data Encryption Standart, стандарт шифрования данных) был разработан в 1973 году компанией IBM и долгое время являлся основным стандартом шифрования в мире. Этот алгоритм использует 56-битный ключ и шифрует данные блоками по 64 бита. Имеет несколько режимов работы, которые применимы и для других блочных шифров симметричной схемы:

n Режим электронной шифровальной книги Electronic Codebook Mode (ECB). Простейший режим. Открытый текст обрабатывается блоками по 64 бита (8 байт) и каждый блок шифруется с одним и тем же ключом (см. рис. 1). Самой важной особенностью режима ECB является то, что одинаковые блоки открытого текста в шифрованном тексте будут также представляться одинаковыми блоками. Поэтому при передаче достаточно длинных сообщений режим ECB не может обеспечить необходимый уровень защиты. Если сообщение имеет явно выраженную структуру, у криптоаналитика появляется возможность использовать регулярности текста. Например, если известно, что в начале сообщения всегда размещается определенный заголовок, криптоаналитик может получить в свое распоряжение целый набор соответствующих пар блоков открытого и шифрованного текста.

Рисунок 1. Режим электронной шифровальной книги ECB

n Режим сцепления шифрованных блоков Cipher Block Chaining Mode (CBC). Эта технология свободна от недостатков режима ECB. В режиме CBC входной блок данных для алгоритма шифрования вычисляется как результат операции XOR текущего блока открытого текста и блока шифрованного текста, полученного на предыдущем шаге (см. рис. 2).

Рисунок 2. Режим сцепления шифрованных блоков CBC

n Режим шифрованной обратной связи Cipher Feedback Mode (CFB). Полученный на предыдущем шаге шифрованный текст используется как входные данные для алгоритма шифрования с целью получения псевдослучайной последовательности (ПСП), XOR-разница которой и блока открытого текста определяет очередной блок шифрованного текста (см. рис. 3)

Рисунок 3. Режим 64-битовой шифрованной обратной связи CFB

n Режим обратной связи по выходу Output Feedback Mode (OFB). Работает подобно CFB, но в качестве входных данных для алгоритма шифрования используются ранее полученные выходные данные DES (см. рис. 4).

Рисунок 4. Режим 64-битовой обратной связи по выходу OFB

Если проводить аналогии с алгоритмом ГОСТ 2814789, то режим ECB соответствует режиму простой замены, OFB - режиму гаммирования, CFB - режиму гаммирования с обратной связью.

Малая длина ключа и постоянно растущая мощность современных вычислительных комплексов сделали алгоритм DES потенциально уязвимым перед атакой, основанной на полном переборе ключей. Это обстоятельство наложило существенные ограничения на использование DES в чистом виде и потребовало поиска альтернативы данному шифру. Один из вариантов решения проблемы предполагал создание совершенно нового алгоритма, другой подход сделал ставку на многократное шифрование с помощью DES с применением нескольких ключей.

Широкое распространение получил "тройной" DES (Triple-DES), представляющий собой последовательность операций шифрования-дешифрования-шифрования (EDE - encrypt-decrypt-encrypt) с использованием трех разных ключей. Схема "тройного" DES представлена на рис. 5.

Рисунок 5. Схема "тройного" DES

"Тройной" DES может также использовать два ключа. В этом случае операции шифрования выполняются на одном ключе, а операция дешифрования - на другом.

Использование функций библиотеки, реализующих алгоритм DES, предполагает два этапа: генерация ключей и собственно шифрование информации.

Генерацию DES-ключа выполняет функция DES_random_key(DES_cblock *ret). Входным параметром функции является указатель на блок данных типа DES_cblock, в котором будет сохранен ключ. Тип DES_cblock определен в файле openssl/des.h, и представляет собой 8-байтовую последовательность с контролем четности. Младший значащий бит каждого байта является битом четности:

typedef unsigned char DES_cblock[8];

После генерации ключ необходимо сконвертировать в платформенно-зависимый формат при помощи функции DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule). Функция принимает два параметра - указатель на сгенерированный ключ и указатель на структуру типа DES_key_schedule. Этот структурный тип определен в файле openssl/des.h. Функция DES_set_key_checked выполняет контроль четности всех байт ключа и проверяет, можно ли использовать его для шифрования, т.е. является ключ криптографически сильным или нет. Если четность байт не соблюдается, функция возвращает -1. Если сгенерированный ключ оказался криптографически слабым (weak), функция возвращает -2. Если ключ удовлетворяет всем требованиям, то он конвертируется в платформенно-зависимый формат и помещается в структуру schedule.

Исходя из вышеизложенного, код генератора ключевой последовательности для алгоритма Triple-DES будет выглядеть следующим образом:

Листинг 4. Генератор ключей для алгоритма Triple-DES

#include <openssl/des.h>