Быстрая схема аутентификации и обмена ключами, устойчивая к DDoS-атаке

Исследование криптографического протокола, способного обеспечить надежную взаимную аутентификацию и обмен ключами, оставаясь наименее уязвимым к DDoS атакам. Анализ существующих аналогичных протоколов. Программная реализация схемы, платформа разработки.

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 11.07.2012
Размер файла 850,3 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Для языка Си характерны лаконичность, стандартный набор конструкций управления потоком выполнения, структур данных и обширный набор операций.

В процессе своего развития язык Си лег в основу языка С++ но так как языки в последствии развивались независимо друг от друга в них стало появляться всё больше и больше несовместимостей.

C++ -- компилируемый статически типизированный язык программирования общего назначения[9].

Данный язык поддерживает такие парадигмы программирования как процедурное программирование, модульность, раздельная компиляция, обработка исключений, абстракция данных, типы (объекты), виртуальные функции, объектно-ориентированное программирование, обобщенное программирование, контейнеры и алгоритмы, сочетает свойства как высокоуровневых, так и низкоуровневых языков. В сравнении с его предшественником -- языком Cи, -- наибольшее внимание уделено поддержке обобщённого и объектно-ориентированного программирования.

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

6.3 Assembler

В данном проекте не будет использоваться непосредственно assembler, но будут использованы небольшие вставки. Приведем краткое описание этого языка для того что бы понять с чем имеем дело.

Assembler - машинно-ориентированный язык программирования низкого уровня с командами, обычно соответствующими командам машины [9]. Язык ассемблера позволяет программисту пользоваться алфавитными мнемоническими кодами операций, по своему усмотрению присваивать символические имена регистрам ЭВМ и памяти, а также задавать удобные для себя схемы адресации. Кроме того, он позволяет использовать различные системы счисления для представления числовых констант и даёт возможность помечать строки программы метками с символическими именами с тем, чтобы к ним можно было обращаться (по именам, а не по адресам) из других частей программы (например, для передачи управления).

Данный язык обычно используется в тех случаях когда критически важны быстродействие или объем используемой памяти. С его помощью можно провести, например, оптимизацию критичных к скорости участков программ написанных на языках высокого уровня.

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

6.4 OpenSSL

OpenSSL -- криптографический пакет с открытым исходным кодом. Данное программное средство основано на библиотеке SSLeay, написанной Эриком Янгом (Eric A. Young) и Тимом Хадсоном (Tim Hudson)[9]. OpenSSL лицензируется по "двойной лицензии" OpenSSL License и SSLeay License, и требует чтобы фраза "This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit. (http://www.openssl.org/)" содержалась в рекламных материалах и при последующем распространении. За исключение приведенных выше аспектов лицензия позволяет свободно использовать OpenSSL в любых как коммерческих так и не коммерческих целях[12].

OpenSSL включает в себя набор криптографических библиотек, в которых реализованы различны алгоритмы симметричного шифрования, криптография с открытым ключом, работа с сертификатами, криптографические хеш функции и генератор псевдослучайных чисел.

1 Симметричные алгоритмы: Blowfish, Camellia, DES, RC2, RC4, RC5, IDEA, AES, ГОСТ 28147-89.

2 Криптография с открытым ключом: DSA, RSA, Diffie-Helman key exchange, ГОСТ Р 34.10-2001.

3 Сертификаты: x509, x509v3

4 Коды аутентификации и хеш функции: hmac, md2, md4, md5, mdc2, ripemd, sha.

5 Вспомогательные функции: err, threads, rand, PENSSL_VERSION_NUMBER

6 Функции кодирования входных\выходных данных: asn1, bio, evp, pem, pkcs7, pkcs12

6.5 Описание используемых алгоритмов

6.5.1 MD5

MD5 -- 128-битный алгоритм хеширования, разработанный профессором Рональдом Л. Ривестом в 1991 году[9]. Алгоритм прост в реализации и предназначен для создания “отпечатка” (fingerprint) или цифровой подписи для сообщений произвольной длины. Предполагается, что для создания двух сообщений с одинаковыми сигнатурами потребуется порядка 2^64 операций, а для подбора сообщения по имеющейся сигнатуре - порядка 2^128 операция[13].

На вход алгоритма поступает входной поток данных, хеш которого необходимо найти. Длина сообщения может быть любой (в том числе нулевой). Запишем длину сообщения в b. Это число целое и неотрицательное. Кратность каким-либо числам необязательна. После поступления данных идёт процесс подготовки потока к вычислениям.

Для создания цифровой подписи выполняется процесс из 5 описанных ниже этапов.

1 Для начала сообщение дополняется до размера кратного 448 по модулю 512. выравнивание происходит даже если длинна уже кратна этому значению. Для этого в конец сообщения добавляют бит равный «1» а затем добавляют биты со значением «0» пока не будет достигнут нужный размер.

2 В оставшиеся 64 бита дописывают 64-битное представление длины данных (количество бит в сообщении) до выравнивания. Сначала записывают младшие 4 байта. Если длина превосходит , то дописывают только младшие биты. После этого длина потока станет кратной 512. Вычисления будут основываться на представлении этого потока данных в виде массива слов по 512 бит.

3 Для расчета цифровой подписи используется буфер на 4 слова (A,B,C,D). каждое из слов A, B, C, D представляет собой 32-битовый регистр. Этим регистрам задаются соответствующие начальные значения.

4 На данном этапе определяются 4 вспомогательные функции каждая из которых принимает три 32-битовых слова в качестве аргументов и возвращает одно 32-битовое слово.

F(X,Y,Z) = XY v not(X) Z

G(X,Y,Z) = XZ v Y not(Z)

H(X,Y,Z) = X xor Y xor Z

I(X,Y,Z) = Y xor (X v not(Z))

Определяется 64-элементная таблица T[1...64], построенная с использованием синусоидальной функции (sine function). Выровненные данные разбиваются на блоки (слова) по 32 бита, и каждый блок проходит 4 раунда из 16 операторов. Все операторы однотипны и имеют вид: [abcd k s i], определяемый как

где X -- блок данных. X[k] = M [n * 16 + k], где k -- номер 32-битного слова из n-го 512-битного блока сообщения, и  -- циклический сдвиг влево на бит полученного 32-битного аргумента.

5 Сигнатура сообщения выводится как A, B, C, D (т. е., мы начинаем вывод с младшего байта A и закачиваем старшим байтом D).

Рисунок 6.1 Схема работы алгоритма MD5

Примеры реализации и подробное рассмотрения алгоритма приведено в[13].

6.5.2 AES

Advanced Encryption Standard (AES), также известный как Rijndael - симметричный алгоритм блочного шифрования с размером блока 128 бит, ключом 128/196/256 бит и количеством раундов 10, 12, или 14 в зависимости от длинны ключа. Оригинальный алгоритм Rijndael имеет возможность работать с более длинным блоком данных но эти модификации не вошли в стандарт AES. Данный алгоритм разработан бельгийскими криптографами В.Рейманом и Й. Даманом. В 2001 году AES был принят в качестве нового стандарта шифрования в США[9,14,15].

Блок входных и выходных данных состоит из 4 слов по 32 бита каждое, в свою очередь ключ состоит из 4, 6 или 8 слов.

Таблица 6.1 Стандартные комбинации длин ключа - блока - раундов

Длинна ключа (Nk слов)

Длинна блока (Nb слов)

Количество раундов

AES 128

4

4

10

AES 196

6

4

12

AES 256

8

4

14

Шифр начинается и заканчивается сложением блока данных с ключом это позволяет закрыть вход первого раунда при атаке по известному тексту, а так же сделать криптографически значимым результат последнего раунда.

Каждый раунд состоит из трех различных обратимых преобразований:

1 Линейный смешивающий слой гарантирует высокую степень взаимопроникновения символов блока для маскировки статических связей.

2 Нелинейный слой реализован с помощью S-блоков, имеющих оптимальную нелинейность, и предотвращает использование дифференциального, линейного и других методов криптоанализа.

3 Слой сложения с ключом на этом этапе выполняется непосредственно шифрование.

Ниже приведена реализация алгоритма на псевдокоде. В качестве входных параметров передается входной блок in и ключ w, на выходе мы получаем шифрованный блок out. В данном примере процедура AddRoundKey реализует слой сложения, SubBytes слой нелинейного преобразования, а ShiftRows и MixColumns реализуют смешивающий слой

Рисунок 6.2 Алгоритм шифрования AES на псевдокоде

6.5.3 RSA

RSA - ассиметричный( с открытым ключом) алгоритм используемый для шифрования и для цифровой подписи сообщения был разработан Рональдом Ривестом, Ади Шамиром и Леонардом Адлеманом в в 1977 году. В настоящее время этот алгоритм широко распространен в различных криптографических приложениях[9].

В системе RSA используется два фактора[14]:

1 Задача проверки числа на простоту которая является относительно легкой

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

Для генерации ключей каждый абонент системы выбирает случайно два больших простых числа P и Q. Затем абонент вычисляет число

N=PQ

После этого вычисляется значение функции Эйлера от этого числа

f=(P-1)(Q-1)

и выбирается число d<f , взаимно простое с f, это число является открытой экспонентой. Далее вычисляется число c такое что

cd mod f = 1

Таким образом, пара чисел {d, N} является открытым ключом, а {с, N} секретным.

Протокол RSA можно описать следующим образом. Пусть Алиса хочет передать Бобу сообщение m такое что m<NB для этого:

1 Алиса шифрует сообщение и передает его бобу

e=mDb mod NB

2 Боб получив сообщение вычисляет

m'=eCb mod NB

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

y=h(m)

Далее Алиса вычисляет число s, сформированным подписанным сообщение будет являться пара чисел {m,s}

s=yCa mod NA

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

w=sDa mod NA

и проверить выполняется ли равенство w=h(m) . В том случае, если равенство верно, проверяющий может быть уверен, что подпись подлинная.

7. РЕАЛИЗАЦИЯ И РУКОВОДСТВО ПРОГРАММИСТА

Как уже говорилось ранее для решения поставленной задачи было разработано клиент серверное приложение в этой главе я приведу подробное описание сервера, клиент, а так же регистратора который отвечает за генерацию ключей RSA.

7.1 Генерация и хранение ключей

В моем проекте за все криптографические функции отвечает библиотека OpenSSL разумеется и генерация ключей не исключение. Данная библиотека позволяет генерировать ключи, различной длинны, для системы RSA, а также имеет генератор псевдослучайных чисел, необходимый при генерации некоторых ключей.

7.1.1 Генерация ключей RSA

Из приведенного в главе 6 описания алгоритма RSA видно, что нет необходимости генерировать новые ключи при каждом его использовании, в связи с этим генерация ключей происходит отдельно от клиентской и серверной части проекта в специально созданной для этих целей программе регистраторе. Регистратор генерирует секретный и публичный ключи длиной 1024 бита и записывает их в файл, при этом секретный ключ дополнительно шифруется по алгоритму Blowfish в режиме 64 битной обратной связи по выходу(ofb) с кодовым словом “Hello”, а от открытого ключа берется хеш по алгоритму MD5. Ключи сохраняются в файлы privat.key, public.key, а так же в файл, именем которого является вычисленный хеш, записывается публичный ключ. Приведем примеры хранения открытого и секретного ключей в файлах

-----BEGIN RSA PUBLIC KEY-----

MIGJAoGBALCXlfUr43iXveg7xV3CR+TWkT/YQrftgxKkO3O0vIiKv59BZCoW0vvv

gQ7mnUB7I1b+hSf4biUDKYacCRPuASh5s6I7M727sjpvuAqsAPYyExjRyBULVXm0

k4GCZKpJsBmA2fDRBAHm/bAOXvR2hNkYWW7lLs1YcZJyQGPdrjNrAgMBAAE=

-----END RSA PUBLIC KEY-----

-----BEGIN RSA PRIVATE KEY-----

Proc-Type: 4,ENCRYPTED

DEK-Info: BF-OFB,8ECB89E89B4AB034

enakf3pEeNkRcnJVBXFyWjRiwhfSLwzB/nFXHT0rP92u28N2gRkMqkT3D4PFAV3x

g7qRH73f0jDRc481yEvQ/kmjgtX0La8z+7pAk4H1v3mkiuZHfWLq/1TjtQ3MAb8Y

XYDjC8QaOQJwJtmBz3+50mDWiEsaE3zVhHUDYWPDEU1SK5hYNjMHK3rFeGdW7ium

rlZCkx2jvoyHdNQVQWILyL8g4nyJoOp47D6rfrp+xEIYK7zOw9vBwdbaTUkqLnYE

o27ev7zBOVeuaDR/vWXJT89RN47VGU/5dHQc0ap0Q022ROBxn0U9jlZIBNFuG3wl

4VZ2VO2OnmrZ0n/NWm3AP+CSEAclDod8K+DLFysKd/4ZPLGQiq+LKITNWTsEOr1b

kdpF1hQqNjExuROCTIGP1R/b5v2KeWKZ2r+q5mPUlOoOV8VqAGkuVvXIMkFBDe2A

iUvWrhghPNZUju/xvjfxXkEYQFMb33wt2oYeBtVy8FIA/8Zf+p1oLrBB3t5SIQB/

duK6RMmK/lHwF+lrWu/r8hrw3bzUcCafb2+/xX4X9RLBLS9huY2sNjPJ3xk1Vqoq

7Ul5osTDHr6NMAjJt7a82Z46CC9IpXJ5D/LdXSKzIK/7NXHbEbAeeb3p5oXWdEa8

kSP+fvUQ2fCmVDhT9f5GzDFRe6HyPdPS54kC432d/UKjkIDKqQsV87W7Mhl1QRJm

8asNr8iJV2V3Bd4tZoXPAE0NOZc4Bel0a/ldAK75ZZ7mRS0lyBsqUDGkE3/eceOo

HekxmoaRfXfqD5nFdWhpUJZVVAuhRk1r3g0y8L4sWj3a

-----END RSA PRIVATE KEY-----

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

7.1.2 Генерация сессионных ключей

В отличии от ключей для системы RSA согласно условиям реализуемого протокола новые ключи должны формироваться при каждом подключении к серверу. Процесс формирования ключей реализован в клиентской части приложения. Для создания ключа с помощью библиотеки OpenSSL генерируется большое псевдослучайное число, а затем от этого числа вычисляется хеш MD5, в результате мы получаем 32 битный ключ после чего повторяем процедуру для получения второго ключа. Данные ключи хранятся как массив unsigned char в переменных session_key1 и session_key2.

7.1.3 Генерация ключей предварительной аутентификации

Согласно требованиям реализуемого протокола ключ предварительной аутентификации вычисляется, как MD5 хеш от ключа сессии при этом хеш первого ключа сессии будет являться идентификатором ключа(IDauthkey), а хеш от второго ключа непосредственно самим ключом (authkey). На стороне клиента идентификатор и ключ хранятся в файлах auth.id и auth.key соответственно, а на стороне сервера ключ хранится в файле, названием которого является идентификатор ключа. На сервере данный ключ изначально отсутствует и генерируется аналогичным образом, но только в том случае если клиент успешно прошел полную аутентификацию, таким образом происходит согласование данных ключей между клиентом и сервером.

7.2 Реализация сервера

Сервер разработан для операционной системы Windows XP, с учётом требований рассматриваемого протокола. Все необходимые для работы приложения библиотеки включены в пакет установки приложения. Перед началом работы необходимо указать нужные параметры в файле конфигурации serv_ini, а также в случаи необходимости сгенерировать новые ключи

Основные функции сервера:

· Настройка

· Прием входящих подключений

· Реализация протокола аутентификации

· Измерение времени работы протокола

· Общение с клиентом

· Логирование

· Подсчет обработанных подключений

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

Рисунок 7.1 Пример работы сервера

7.2.1 Настройка

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

Структура файла конфигурации serv_ini

· Порт для приема входящих подключений

· Задержка после приема подключения в миллисекундах

· Задержка во время работы нити в миллисекундах.

· Количество проходов алгоритма после которого будет высчитано среднее время работы

· Время в миллисекундах превышение которого будет считаться не корректным

· Количество сообщений которыми обменяется сервер и клиент перед разрывом соединения в случае успешной аутентификации.

· Длина этих сообщений

· Флаг использования задержки в нутрии нити (1 использовать)

· Флаг определяющий будет ли в расчет включаться время генерации ключей предварительной аутентификации (1 включать)

· Флаг отвечающий за общение с клиентом по мимо основного протокола, то есть за пересылку сообщений перед разрывом соединения в случае успешной аутентификации (1 разрешить)

· Флаг определяющий будет ли использовать предварительная аутентификация (1 использовать)

7.2.2 Прием входящих подключений

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

7.2.3 Реализация протокола аутентификации

Реализации протокола происходит в нутрии нити. От клиента принимается некий пакет данных, затем этот пакет разбивается функцией split_pakage на 4 поля P1 P2 P3 P4, Эти поля представляют собой массив символов unsigned char. После разбиения пакета начинается процедура предварительной аутентификации. Функция get_authkey принимает на вход поле P3 и массив authkey, она извлекает ключ предварительной аутентификации и в случае успеха возвращает 0. Если ключ был успешно получен то в функцию pre_auth перадетются поля P1 P4 и ключ, эта функция шифрует поле P1 алгоритмом AES и сравнивает его с P4 если они равны возвращает 0, что означает об успешном прохождении предварительной аутентификации. В случае если неудалось извлеч ключ или предварительная аутентификация была не пройдена приоритет нити понижается в противном случае приоритет остается неизменным. Следующим шагом является расшифровка поля P1 алгоритмом RSA на SKS для этого оно передается в функцию do_decrypt также туда передается массив ptext в который будет записан расшифрованный текст. После расшифровки это поле разбивается на два сессионных ключа и id публичного ключа клиента функцией split_P1. Теперь когда нам известе id извлекаем ключ из файла функцией get_PKC на вход она принимает id а возвращет структуру RSA, в которой хранится публичный ключь клиента, либо NULL. В том случае если PKC не был получен сервер отказывает клиенту в аутентификации, вызывает функцию make_replay которая формирует соответсвующий ответ, а затем отправляет этот ответ клиенту и разрывает соединение. Если же PKC был получен корректно вычисляется MD5 хеш от поля P1, функцией do_DECRYPT_AES на первом ключе сессии расшифровывается поле P2, после чего хеш и расшифрованные данные передаются в функцию do_verify которая проверяет правильность подписи и в случае успеха возвращает 0. Если подпись оказалась подлинной то аутентификация считается успешной об этом функцией make_replay создается соответствующее сообщение, которое шифруется алгоритмом AES на втором ключе сессии, данное сообщение передается клиенту и функцией gen_authkey генерируются новый IDauthkey и authkey. После этого если небыл установлен флаг диалога соединение разрывается. Если же подпись оказалась фальшивой то опять же функцией make_replay формируется сообщение об этом и отправлется клиенту, после чего соединение разрывается.

7.2.4 Измерение времени работы протокола

Данная задача является критически важной для данного проекта и измерение времени должно быть максимально точным, поэтому для реализации этой задачи было принято решение использовать ассемблерную вставку.

unsigned __int64 rdtsc() {

_asm{

rdtsc

}

}

Данная функция возвращает значение счетчика циклов процессора. Как было описано выше, на стадии инициализации сервер вычисляет среднее изменения этого счетчика за секунду, это позволяет нам переводить полученное значение в миллисекунды по формуле

(t2-t1)/avgt*1000

где t2- значение счетчика в конце протокола t1 - в начале а avgt- среднее значение за секунду.

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

7.2.5 Общение с клиентом

Одной из целей дипломного проекта была исследование предложенного протокола аутентификации и обмена ключами. Так как для достижения этой цели необходимо было не только реализовать протокол, но и создать условия работы сервера в реальных условиях, была создана функция общения с клиентом. Данная функция имитирует присутствие легального пользователя в системе путем взаимного обмена с клиентом сообщениями. Процедура общения начинается с пересылки клиенту параметров, а именно количества сообщений и длинны сообщений, в ответ клиент присылает согласие или отказ от общения. В случае согласия клиент присылает первое сообщение, которое передается функции dialog, эта функция расшифровывает принятое сообщение по алгоритму AES на втором ключе сессии, затем создает новое сообщение и также шифрует его, после этого сообщение передается клиенту. Процедура повторяется до тех пор пока соединение не будет разорвано или не будут переданы все сообщения.

7.2.6 Логирование

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

Система логирования разделена на две части. Первая часть отвечает за запись различных исключительных ситуаций, которые могут возникнуть в процессе работы сервера. Информация о них записывается в файл log_error.txt, запись содержит короткое пояснение и код ошибки. Пример такой записи «WSAStart error 10048» данная запись говорит о том, что не удалось открыть заданный порт так как он уже используется, код ошибки сформирован функцией WSAGetLastError() библиотеки winsock полный список можно найти на официальном сайте[16].

Вторая часть отвечает за запись информации о времени работы протокола и расчет большой и малой средних. Малая средняя вычисляется как среднее время работы протокола за последние n раз, n указывается в файле конфигурации, большая средняя вычисляется из 10 малых. Данные о каждом проходе протокола записываются в файл log.txt в формате «результат аутентификации» «результат предварительной аутентификации» «количество подключенных клиентов на момент записи» «время работы протокола в миллисекундах». Данные о средних записываются в файл log_AVG.txt в формате «результат аутентификации» «результат предварительной аутентификации» «большая\малая средняя» «среднее значение времени в милисекундах». Примеры логов: «succeed 0 23 17.308069 ms», «failed SIGN 1 27 17.768198 ms» , «legal up client time avg=17.059146», «failed SIGN client time avg=17.355597».

7.3 Реализация клиента

Клиент также как и сервер реализован для операционной системы Windows XP и соответствует требованиям, предъявленным к протоколу. Все необходимые для работы приложения библиотеки включены в пакет установки приложения. Перед началом работы необходимо указать нужные параметры в файле конфигурации conin, а также в случаи необходимости сгенерировать новые ключи. Клиент реализует свою часть протокола и используется для моделирования действий легального пользователя, а так же для моделирования DDoS атаки.

Основные функции клиента:

· Настройка

· Подключение к серверу

· Реализация протокола аутентификации

· Общение с сервером

· Имитация действий не легального пользователя

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

Рисунок 7.2 Пример работы клиента

7.3.1 Настройка

Как и серверная часть, клиент настраивается с помощью файла конфигурации conin. Функция client_ini() извлекает из него всю необходимую информацию.

Структура файла конфигурации:

· Порт необходимый для подключения

· IP-адрес сервера

· Флаг, отвечающий за генерацию ключей предварительной аутентификации (0 генерировать)

· Флаг, отвечающий за реализацию общения с сервером (0 разрешить общение)

· Флаг DDoS клиента (1 переключает клиента в режим флуд атаки)

· Задержка между сообщениями в процессе диалога в миллисекундах

· Задержка перед повторением протокола в миллисекундах

7.3.2 Подключение к серверу

Новое подключение создается при каждом прохождении протокола с помощью функции Connect библиотеки winsock.h на основании параметров указанных в файле конфигурации, и разрывается после окончания работы протокола или в случае невозможности передать данные. В том случае, если по каким либо причинам не удалось подключиться к серверу, осуществляется еще 5 попыток подключения с задержкой в 2000 миллисекунд, если соединения установить так и не удалось, программа завершает свою работу.

7.3.3 Реализация протокола аутентификации

После успешного подключения начинается создание пакета для отправки серверу. Реализация протокола начинается с генерации двух ключей сессии функцией gen_session_key которая принимает на вход массив для храния ключа, сама процедура генерации была описана в разделе 7.1.2 ПЗ. Затем вычисляется MD5 хеш от публичного ключа клиента, который является идентификатором(IDc) клиента. Далее эти данные объединяются в массив ptext и передаются в функцию do_encrypt которая извлекает из файла публичный ключ сервера и шафрует на нем полученные данные с помощью алгоритма RSA после чего записывает зашифрованные данные в массив P1. После этого от поля P1 вычисляется хеш MD5 и передается в функцию do_sign которая подписывает его на секретном ключе клиента и записывает подпись в поле P2, затем это поле шифруется алгоритмом AES на первом ключе сессии функцией do_AES. Следующим шагом является извлечение из файлов ид и ключа предварительной аутентификации, а так же генерация нового ключа и идентификатора и замена их в файлах, за это отвечают функции get_IDauthkey, так же она заносить идентификатор в поле P3, и get_authkey. Затем поле P1 шифруется по алгоритму AES на ключе предварительной аутентификации с помощью функции do_AES, полученные данные заносятся в поле P4. Функция make_send_package объединяет все 4 поля и подготавливает их к отправке на сервер. После отправки данных клиент ожидает ответа от сервера если ответ не был получен то соединение разрывает и алгоритм повторяется заново, если ответ был получен то полученный пакет данных передается в функцию replay которая расшифровывает его и возвращает 1 если аутентификация прошла успешна.

На этом протокол аутентификации считается завершенным, соединение разрывается, и вся процедура вместе с установление нового подключения повторяется.

7.3.4 Общение с сервером

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

7.3.5 Имитация действий не легального пользователя

Для моделирования DDoS атаки нам необходимо реализовать протокол как со стороны легального, так и со стороны не легального пользователя.

Для реализации действий легального пользователя флаги DDoS клиента и генерации ключей предварительной аутентификации должны быть установлены на 0. Так же программе должны быть переданы легальные ключи системы RSA как клиента, так и сервера.

Действия «пхого» клиента реализуются двумя способами:

1 Использование заведомо неверных ключей RSA. Можно изменить любой ключ, но я рекомендую в качестве неверного ключа использовать только SCK, так как при таком подходе сервер будет обязан провести полную проверку принятых данных.

2 Второй способ это установление файла DDoS атаки в 1. В этом случае после отправки пакета серверу клиент, не дожидаясь ответа, будет разрывать соединение после небольшой задержки, и вновь подключаться к серверу. При таком подходе будет осуществляться спам атака на сервер, при этом, благодаря небольшой задержке перед разрывом соединения, сервер будет обязан обработать принятые данные что также займет какое то количество времени и ресурсов.

8. ИССЛЕДОВАНИЕ ПРОТОКОЛА

8.1 Тестирование протокола в различных условиях

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

Для того чтобы оценить реальную пользу от такого подхода необходимо провести тестирование протокола, смоделировав реальные условия DDoS атаки.

Первый этап тестирования проводился на локальной машине с процессором DualCore AMD Athlon II X2 240, 2800 MHz (14 x 200) и памятью 3328 Мб (DDR2 SDRAM).

Тест № 1.

Целью данного теста является показать изменение времени работы протокола с увеличением числа подключаемых легальных пользователей. Тест начинается с подключения двух клиентов которые после прохождения процедуры аутентификации обмениваются с сервером сотней сообщений длинной 50 символов и подключаются заново после каждого сотого подключения добавлялось еще 2 клиента. Время потраченное на пересылку этих сообщений и на генерацию новых ключей предварительной аутентификации не учитывалось, для более наглядного сравнения со временем обработки нелегальных пользователей полученным в следующих тестах. На основании полученных логов сервера был составлен график изображенный на рисунке 8.1, использовались средние значения за 100 подключений. Всего в ходе теста было задействовано 26 клиентов и обработано 3000 подключений.

Рисунок 8.1 Тест №1 приоритет реального времени

Рисунок 8.2 Тест №1 повышенный приоритет

Библиография

1 Б.Шнаер. Прикладная криптография: Протоколы, алгоритмы, исходные тексты на языке Си. «Триумф», 2002.

2 A. Menezes, P. van Oorshort, S. Vanstone. Handbook of applied cryptography. CRCPress, 1996.

3 Дж. Скембрей, С. Мак-Клар, Дж. Курц. Секреты хакеров. Безопасность сетей - готовые решения. Второе издание. «Вильямс», 2001

4 Дж. Вакка. Секреты безопасности в Internet. «Диалектика», 1997.

5 В.М. Зима, А.А. Молдовян, Н.А. Молдовян. Безопасность глобальных сетевых технологий. БХВ-Петербург, 2000.

6 J.Postel. Transmission Control Protocol. RFC 793.

7 Н.Вирт. Алгоритмы и структуры данных. "Мир", 1989

8 Чмора А.Л. Современная прикладная криптография. 2-е изд., стер. - М.: Гелиос АРВ, 2002.

9 Wikipedia, the free encyclopedia [Электронный ресурс]: Cвободная общедоступная многоязычная универсальная энциклопедия. -- Режим доступа: http://ru.wikipedia.org/wiki/Main_Page.

10 M. Burrows, M. Abadi, R. Needham A Logic of Authentication // Research Report 39, Digital Equipment Corp. Systems Research Center -- Feb. 1989

11 Microsoft Visual Studio 2010 [Электронный ресурс]: Официальный сайт Visual Studio 2010. - Режимдоступа: http://microsoft.com/visualstudio/ru-ru.

12 OpenSSL: The Open Source toolkit for SSL/TLS[Электронный ресурс]: Официальный сайт разработчиков библиотеки OpenSSL. - Режим доступа: http://openssl.org

13 R. Rivest. The MD5 Message-Digest Algorithm. RFC 1321.

14 Рябко Б. Я., Фионов А.Н. Основы современной криптографии для специалистов в информационных технологиях. - М.: Научный мир, 2004.

15 FIPS 197. The advanced encryption standart (AES)., 2001.

16 MSDN Library [Электронный ресурс]: информация для разработчиков использующих продукты Microsoft - режим доступа : http://msdn.microsoft.com/en-us/library

ПРИЛОЖЕНИЕ А

Наиболее употребляемые текстовые сокращения

ВС - вычислительная система

ПЗ - пояснительная записка

АСУ - автоматизированная система управления

ДП - дипломный проект

ПЗ - пояснительная записка

СибГУТИ - Сибирский государственный университет телекоммуникаций и информатики

ПРИЛОЖЕНИЕ Б

Листинг исходного кода программного средства

// full_tcp_serv.cpp : Defines the entry point for the console application.

// server part

#include "stdafx.h"

#include <stdio.h>

#include <winsock.h>

#include <process.h>

#include <windows.h>

#include <openssl/rsa.h>

#include <openssl/pem.h>

#include <openssl/md5.h>

#include <openssl/rand.h>

#include <openssl/applink.c>

#include <stdlib.h>

#include <malloc.h>

#include <mbstring.h>

#include <iostream>

#pragma comment (lib,"libeay32")

#pragma comment (lib,"ssleay32")

#pragma comment (lib,"wsock32")

#define BUFSIZE 1024

#define BUFFSIZE (1025*16)

#define PRIVAT_SERVER_KEY "privat_server.key"

#define PUBLIC_SERVER_KEY "public_server.key"

#define PUBLIC_CLIENT_KEY "public_client.key"

#define password "hello"

#define KEYSIZE 32

#define RSA_key_size 128

#define _CRT_SECURE_NO_WARNINGS

CRITICAL_SECTION cs1;

CRITICAL_SECTION cs2;

CRITICAL_SECTION cs3;

CRITICAL_SECTION cs4;

int num_connect=0;

u_short PORT=3425;

RSA *pub_serv;

RSA *priv_serv;

FILE *log,*log1,*log2;

float tik_per_second;

int config_param[10];

int config_flags[10];

float counter[8],savg[8];

unsigned __int64 rdtsc() {

return __rdtsc();

}

int servini(){

FILE * pub_key_file = NULL;

FILE * priv_key_file = NULL;

FILE * ini;

int i=0;

float tmp[10];

unsigned __int64 t1, t2;

const EVP_CIPHER *cipher = NULL;

OpenSSL_add_all_ciphers();

cipher = EVP_get_cipherbyname("bf-ofb");

SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);

fopen_s(&ini,"serv_ini","r+");

fscanf(ini,"%d",&PORT);

fscanf(ini,"%d",&config_param[0]);

fscanf(ini,"%d",&config_param[1]);

fscanf(ini,"%d",&config_param[2]);

fscanf(ini,"%d",&config_param[3]);

fscanf(ini,"%d",&config_param[4]);

fscanf(ini,"%d",&config_param[5]);

fscanf(ini,"%d",&config_flags[0]);

fscanf(ini,"%d",&config_flags[1]);

fscanf(ini,"%d",&config_flags[2]);

fscanf(ini,"%d",&config_flags[3]);

fscanf(ini,"%d",&config_flags[4]);

while(i<10){

t1 = rdtsc ();

Sleep(1000);

t2 = rdtsc ();

tik_per_second=t2-t1;

if(time>0){

tmp[i]=tik_per_second;

i++;

}

}

tik_per_second=0;

for(int j=0;j<10;j++){

tik_per_second+=tmp[j];

}

tik_per_second/=10;

printf("%f",tik_per_second);

for(int i=0; i<8; i++){

counter[i]=0;

savg[i]=0;

}

if((fopen_s(&log1,"log_error.txt", "w+"))!=0){

exit(-1);

}

if((fopen_s(&log,"log.txt", "w+"))!=0){

fprintf(log1,"error open log file");

exit(-1);

}

if((fopen_s(&log2,"log_AVG.txt", "w+"))!=0){

fprintf(log1,"error open AVG log file");

exit(-1);

}

if((fopen_s(&pub_key_file,PUBLIC_SERVER_KEY, "rb"))!=0){

fprintf(log1,"error open PUBLIC_SERVER_KEY");

exit(-1);

}

else{

pub_serv = PEM_read_RSAPublicKey(pub_key_file, NULL, NULL, NULL);

}

if((fopen_s(&priv_key_file,PRIVAT_SERVER_KEY, "rb"))!=0){

fprintf(log1,"error open PRIVAT_SERVER_KEY");

exit(-1);

}

else{

priv_serv = PEM_read_RSAPrivateKey(priv_key_file, NULL, NULL, "hello");

}

return 0;

}

int md5(unsigned char *str, unsigned char *md_value, int strlen){

EVP_MD_CTX mdctx;

const EVP_MD * md;

unsigned int md_len;

OpenSSL_add_all_digests();

md = EVP_get_digestbyname("md5");

EVP_DigestInit(&mdctx, md);

EVP_DigestUpdate(&mdctx, str, strlen);

EVP_DigestFinal(&mdctx, md_value, &md_len);

EVP_MD_CTX_cleanup(&mdctx);

return 1;

}

int do_DECRYPT_AES(unsigned char *k, char *str, int strlen)

{

int outlen;

unsigned char key[32]; /* 256- битный ключ */

unsigned char iv[8]; /* вектор инициализации */

unsigned char inbuf[BUFSIZE], outbuf[BUFSIZE];

for(int i=0; i<32; i++){

key[i]=k[i];

}

memcpy(inbuf,str,strlen);

EVP_CIPHER_CTX ctx;

const EVP_CIPHER * cipher;

EVP_CIPHER_CTX_init(&ctx);

cipher = EVP_aes_256_cfb();

EVP_DecryptInit(&ctx, cipher, key, iv);

EVP_DecryptUpdate(&ctx, outbuf, &outlen,inbuf, strlen);

memcpy(str,outbuf,strlen);

EVP_EncryptFinal(&ctx, outbuf, &outlen);

EVP_CIPHER_CTX_cleanup(&ctx);

return 0;

}

int do_AES(unsigned char *k, char *str, int strlen)

{

int outlen;

unsigned char key[32]; /* 256- битный ключ */

unsigned char iv[8]; /* вектор инициализации */

unsigned char inbuf[BUFSIZE], outbuf[BUFSIZE];

for(int i=0; i<32; i++){

key[i]=k[i];

}

memcpy(inbuf,str,strlen);

EVP_CIPHER_CTX ctx;

const EVP_CIPHER * cipher;

EVP_CIPHER_CTX_init(&ctx);

cipher = EVP_aes_256_cfb();

EVP_EncryptInit(&ctx, cipher, key, iv);

EVP_EncryptUpdate(&ctx, outbuf, &outlen, inbuf, strlen);

memcpy(str,outbuf,strlen);

EVP_EncryptFinal(&ctx, outbuf, &outlen);

EVP_CIPHER_CTX_cleanup(&ctx);

return 1;

}

int do_decrypt(unsigned char *ctext, unsigned char *ptext){

int outlen;

int key_size = RSA_size(priv_serv);

outlen = RSA_private_decrypt(key_size, ctext, ptext, priv_serv, RSA_PKCS1_PADDING);

if(outlen < 0){

fprintf(log1,"error: do_decrypt failed;");

}

return 0;

}

int do_verify(unsigned char *m, unsigned int m_len, unsigned char *ctext, unsigned int key_size, RSA *pubKey){

if(RSA_verify(1,m,m_len,ctext,key_size,pubKey)==1){

return 0;

}

else{

return 1;

}

}

int to_hex(unsigned char *str_dest, unsigned char *str_src, int sstr_len){

char tmp[4],buf1[RSA_key_size+1];

for(int i=0; i<sstr_len; i+=2){

sprintf(tmp,"%02x",str_src[i/2]);

sprintf(&buf1[i],"%c",tmp[0]);

if(i+1<sstr_len)

sprintf(&buf1[i+1],"%c",tmp[1]);

}

memcpy(str_dest,buf1,sstr_len+1);

return 0;

}

int split_pakage(char *pakage, unsigned char *P1, unsigned char *P2, unsigned char *P3, unsigned char *P4){

char buf[RSA_key_size+1];

char buf2[KEYSIZE+1];

int count=0;

for(int i=0; i<RSA_key_size; i++){

buf[i]=pakage[count];

count++;

}

memcpy(P1,buf,RSA_key_size);

for(int i=0; i<RSA_key_size; i++){

buf[i]=pakage[count];

count++;

}

memcpy(P2,buf,RSA_key_size);

for(int i=0; i<KEYSIZE; i++){

buf2[i]=pakage[count];

count++;

}

memcpy(P3,buf2,KEYSIZE);

for(int i=0; i<RSA_key_size; i++){

buf[i]=pakage[count];

count++;

}

memcpy(P4,buf,RSA_key_size);

return 0;

}

int make_replay(char *buff, int mode,unsigned char *k2){

char tmp[]="Hello,clien";

char tmp1[]="dialogstart";

if(mode==1){

memcpy(buff,tmp,11);

do_AES(k2,tmp,11);

for(int i=0;i<11;i++){

buff[i+11]=tmp[i];

}

buff[23]='\0';

return 1;

}

if(mode==0){

buff="authentication failed";

return 1;

}

if(mode==2){

memcpy(buff,tmp1,11);

do_AES(k2,tmp1,11);

for(int i=0;i<11;i++){

buff[i+11]=tmp1[i];

}

buff[23]='\0';

return 1;

}

return 0;

}

int split_P1(unsigned char *K1, unsigned char *K2, unsigned char *IDc, unsigned char *ptext){

for(int i=0; i<KEYSIZE; i++){

K1[i]=ptext[i];

K2[i]=ptext[KEYSIZE+i];

IDc[i]=ptext[(KEYSIZE*2)+i];

}

K1[KEYSIZE]=K2[KEYSIZE]=IDc[KEYSIZE]='\0';

return 0;

}

int get_authkey(unsigned char *IDauthkey, unsigned char *authkey){

FILE *f;

char buf[KEYSIZE+3]="1\\",tmp[33];

memcpy(tmp,IDauthkey,32);

tmp[32]='\0';

for(int i=0; i<KEYSIZE;i++){

buf[i+2]=tmp[i];

}

if((fopen_s(&f,buf,"r+"))==0){

if((fread(authkey,1,33,f))!=0){

fclose(f);

std::remove(buf);

return 0;

}

fclose(f);

return 1;

}

return 1;

}

RSA *get_PKC(unsigned char *IDc, RSA *pubKey){

FILE *pub_key_file;

char buf[33];

memcpy(buf,IDc,32);

buf[32]='\0';

if((fopen_s(&pub_key_file,buf, "rb"))==0){

pubKey = PEM_read_RSAPublicKey(pub_key_file, NULL, NULL, NULL);

fclose(pub_key_file);

return pubKey;

}

else{

fprintf(log1,"error: can not open PKC fail");

}

return NULL;

}

int pre_auth(unsigned char *P1, unsigned char *P4, unsigned char *authkey){

char buf[RSA_key_size+1];

unsigned char tmp[RSA_key_size+1];

memcpy(buf,P1,RSA_key_size);

do_AES(authkey,buf,RSA_key_size);

memcpy(tmp,buf,RSA_key_size);

tmp[RSA_key_size]='\0';

P4[RSA_key_size]='\0';

if((_mbscmp(P4,tmp))==0){

return 0;

}

return 1;

}

int gen_authkey(unsigned char *k1, unsigned char *k2){

char buf[KEYSIZE+1];

char tmp1[KEYSIZE+4]="1\\";

unsigned char tmp[KEYSIZE+1];

FILE *f;

md5(k1,tmp,KEYSIZE);

to_hex(tmp,tmp,KEYSIZE);

memcpy(buf,tmp,KEYSIZE);

buf[KEYSIZE]='\0';

for(int i=0; i<KEYSIZE;i++){

tmp1[i+2]=buf[i];

}

fopen_s(&f,tmp1,"w+");

md5(k2,tmp,KEYSIZE);

to_hex(tmp,tmp,KEYSIZE);

fwrite(tmp,1,KEYSIZE+1,f);

fclose(f);

return 0;

}

int dialog(char *buf,int strlen, unsigned char *session_key){

char tmp[10];

do_DECRYPT_AES(session_key,buf,strlen);

for(int i=0; i<strlen; i++){

_itoa(i,tmp,10);

buf[i]=tmp[0];

}

do_AES(session_key,buf,strlen);

return 0;

}

unsigned __stdcall servprotocol( void* pArguments ){

RSA *pubKey=NULL;

char buff[BUFSIZE],tmp1[10];

unsigned char tmp[RSA_key_size+1];

unsigned char authkey[KEYSIZE+1];

unsigned char session_key1[KEYSIZE+1], session_key2[KEYSIZE+1], IDc[KEYSIZE+1], P1[RSA_key_size+1], P2[RSA_key_size+1], P3[KEYSIZE+1], P4[RSA_key_size+1];

unsigned char ptext[RSA_key_size+1];

int byte_read, paflag=0,client_speak=0;;

unsigned __int64 t1,t2;

float cur_tik,cur_time;

SOCKET sock1=((SOCKET *) pArguments)[0];

THREAD_PRIORITY_BELOW_NORMAL);

if((byte_read=recv(sock1, buff, 417,0))>0){

if(config_flags[0]==1)

Sleep(config_param[1]);

t1 = rdtsc ();

split_pakage(buff,P1,P2,P3,P4);

if(config_flags[4]==1){

EnterCriticalSection(&cs3);

if((get_authkey(P3,authkey))==0){

LeaveCriticalSection(&cs3);

if((pre_auth(P1,P4,authkey))==0){

paflag=0;

}

}

else{

LeaveCriticalSection(&cs3);

SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);

paflag=1;

}

}

if(config_flags[3]==1)

Sleep(1);

EnterCriticalSection(&cs1);

do_decrypt(P1,ptext);

LeaveCriticalSection(&cs1);

split_P1(session_key1, session_key2,IDc,ptext);

EnterCriticalSection(&cs2);

pubKey=get_PKC(IDc,pubKey);

LeaveCriticalSection(&cs2);

if(pubKey!=NULL){

md5(P1,tmp,RSA_key_size);

to_hex(tmp,tmp,KEYSIZE);

memcpy(buff,P2,RSA_key_size);

do_DECRYPT_AES(session_key1, buff, RSA_key_size);

memcpy(P2, buff, RSA_key_size);

P2[RSA_key_size+1]='\0';

if((do_verify(tmp,32,P2,RSA_key_size,pubKey))==0){

if(config_flags[1]==1 && config_flags[4]==1)

gen_authkey(session_key1,session_key2);

t2 = rdtsc ();

cur_tik=t2-t1;

cur_time=cur_tik/tik_per_second*1000;

fprintf(log,"\nsucceed %d %d %f ms\n",paflag,num_connect, cur_time);

if(config_flags[2]!=1){

make_replay(buff,1,session_key2);

send(sock1,buff,25,0);

if(config_flags[1]!=1 && config_flags[4]==1)

gen_authkey(session_key1,session_key2);

}

else{

make_replay(buff,2,session_key2);

send(sock1,buff,25,0);

if(config_flags[1]!=1)

gen_authkey(session_key1,session_key2);

if((byte_read=recv(sock1, buff, config_param[5],0))>0){

memcpy(tmp1,buff,byte_read);

if(strcmp(tmp1,"ok")==0){

itoa(config_param[4],buff,10);

byte_read=send(sock1,buff,config_param[4],0);

byte_read=recv(sock1, buff, config_param[5],0);

itoa(config_param[5],buff,10);

byte_read=send(sock1,buff,config_param[5],0);

while(client_speak<config_param[4]){

if((byte_read=recv(sock1, buff, config_param[5],0))>0){

dialog(buff,config_param[5],session_key2);

send(sock1,buff,config_param[5],0);

client_speak++;

}

else{

client_speak+=config_param[4];

}

}

}

}

}

if(closesocket(sock1)!=0){

fprintf(log1,"close sock1 eror (succeed auth)");

}

EnterCriticalSection( &cs4 );

if(paflag==0){

if(cur_time<config_param[3])

savg[0]+=cur_time;

counter[0]++;

if(counter[0]>=config_param[2]){

fprintf(log2,"\nlegal up client time avg=%f\n",savg[0]/counter[0]);

savg[4]+=savg[0]/counter[0];

counter[4]++;

savg[0]=0;

counter[0]=0;

if(counter[4]>10){

fprintf(log2,"\n\nlegal up client time AVG= %f\n\n",savg[4]/counter[4]);

savg[4]=0;

counter[4]=0;

}

}

}

if(paflag==1){

if(cur_time<config_param[3])

savg[1]+=cur_time;

counter[1]++;

if(counter[1]>=config_param[2]){

fprintf(log2,"\nlegal down client time avg=%f\n",savg[1]/counter[1]);

savg[5]+=savg[1]/counter[1];

counter[5]++;

savg[1]=0;

counter[1]=0;

if(counter[5]>10){

fprintf(log2,"\n\nlegal down client time AVG= %f\n\n",savg[5]/counter[5]);

savg[5]=0;

counter[5]=0;

}

}

}

num_connect--;

LeaveCriticalSection( &cs4 );

_endthreadex( 0 );

return 0;

}

else{

t2 = rdtsc ();

cur_tik=t2-t1;

cur_time=cur_tik/tik_per_second*1000;

fprintf(log,"\nfailed SIGN %d %d %f ms\n",paflag,num_connect, cur_time);

make_replay(buff,0,session_key2);

send(sock1,buff,22,0);

if(closesocket(sock1)!=0){

fprintf(log1,"close sock1 eror (failed sign)");

}

EnterCriticalSection( &cs4 );

if(cur_time<config_param[3])

savg[2]+=cur_time;

counter[2]++;

if(counter[2]>=config_param[2]){

fprintf(log2,"\nfailed SIGN client time avg=%f\n",savg[2]/counter[2]);

savg[6]+=savg[2]/counter[2];

counter[6]++;

savg[2]=0;

counter[2]=0;

if(counter[6]>10){

fprintf(log2,"\n\nfailed SIGN client time AVG= %f\n\n",savg[6]/counter[6]);

savg[6]=0;

counter[6]=0;

}

}

num_connect--;

LeaveCriticalSection( &cs4 );

_endthreadex( 0 );

return 0;

}

}

else{

t2 = rdtsc ();

cur_tik=t2-t1;

cur_time=cur_tik/tik_per_second*1000;

fprintf(log,"\nfailed PKC %d %d %f ms\n",paflag,num_connect, cur_time);

make_replay(buff,0,session_key2);

send(sock1,buff,22,0);

if(closesocket(sock1)!=0){

fprintf(log1,"close sock1 eror (failed PKC)");

}

EnterCriticalSection( &cs4 );

if(cur_time<config_param[3])

savg[3]+=cur_time;

counter[3]++;

if(counter[3]>=config_param[3]){

fprintf(log2,"\nfailed PKC client time avg=%f\n",savg[3]/counter[3]);

savg[7]+=savg[3]/counter[3];

counter[7]++;

savg[3]=0;

counter[3]=0;

if(counter[7]>10){

fprintf(log2,"\n\nfailed PKC client time AVG= %f\n\n",savg[7]/counter[7]);

savg[7]=0;

counter[7]=0;

}

}

num_connect--;

LeaveCriticalSection( &cs4 );

_endthreadex( 0 );

return 0;

}

}

else{

fprintf(log1,"\nRECV from client failed\n sock1=%d\n",sock1);

if(closesocket(sock1)!=0){

fprintf(log1,"\nclose sock1 eror (failed PKC)\n");

}

EnterCriticalSection( &cs4 );

num_connect--;

LeaveCriticalSection( &cs4 );

_endthreadex( 0 );

return 0;

}

}

int _tmain(void)

{

SOCKET client_sock, listener;

struct sockaddr_in addr, client_addr;

int count=0;

unsigned threadID;

char buf[1024];

servini();

InitializeCriticalSection( &cs1 );

InitializeCriticalSection( &cs2 );

InitializeCriticalSection( &cs3 );

InitializeCriticalSection( &cs4 );

if ( WSAStartup(0x202,(WSADATA*)&buf[0])){

printf("WSAStart error %d\n", WSAGetLastError());

fprintf(log,"WSAStart error %d\n", WSAGetLastError());

return -1;

}

listener=socket(AF_INET, SOCK_STREAM, 0);

if(listener < 0){

printf("WSAStart error %d\n", WSAGetLastError());

fprintf(log1,"WSAStart error %d\n", WSAGetLastError());

return -1;

}

addr.sin_family=AF_INET;

addr.sin_port=htons(PORT);

addr.sin_addr.s_addr=INADDR_ANY;

if(bind(listener, (struct sockaddr*)&addr, sizeof(addr))<0){

printf("WSAStart error %d\n", WSAGetLastError());

fprintf(log1,"WSAStart error %d\n", WSAGetLastError());

return -1;

}

printf("bind OK\n");

listen(listener, 0x100);

int client_addr_size=sizeof(client_addr);

while(client_sock=accept(listener, (sockaddr *)&client_addr, &client_addr_size)){

count ++;

printf("\nNEW CONNECTION %d\n",count);

EnterCriticalSection( &cs4 );

num_connect++;

LeaveCriticalSection( &cs4 );

_beginthreadex( NULL, 0, &servprotocol, &client_sock, 0, &threadID );

Sleep(config_param[0]);

}

printf("\n\n\n\tSOCK ACCEPT ERROR!!!\n");

fprintf(log1,"\n\n\n\tSOCK ACCEPT ERROR!!!\n");

Sleep(30000);

closesocket(client_sock);

closesocket(listener);

return 0;

}

// full_d_tcp_client.cpp : Defines the entry point for the console application.

// client part

#include "stdafx.h"

#include <stdio.h>

#include <winsock.h>

#include <openssl/rsa.h>

#include <openssl/pem.h>

#include <openssl/md5.h>

#include <openssl/rand.h>

#include <openssl/applink.c>

#include <stdlib.h>

#include<malloc.h>

#include <iostream>

#pragma comment (lib,"libeay32")

#pragma comment (lib,"ssleay32")

#pragma comment (lib,"wsock32");

#define BUFSIZE 1024

#define BUFFSIZE (1025*16)

#define PRIVAT_CLIENT_KEY "privat_client.key"

#define PUBLIC_CLIENT_KEY "public_client.key"

#define PUBLIC_SERVER_KEY "public_server.key"

#define IDauthkey_file "auth.id"

#define authkey_file "auth.key"

#define password "hello"

#define KEYSIZE 32

#define RSA_key_size 128

int PORT=3425;

char SERVERADDR[]="178.49.183.9";

int config_flags[10], config_param[10];

using namespace std;


Подобные документы

  • DDoS атаки. Спасение от DDoS атак. Предотвращение DDoS атак. Аппаратная защита программного обеспечения, компьютера и информации, сети. Хакинг, как сфера исследования. Типы хакеров. Методы хакинга. Защита от программ Microsoft. CMOS SETUP.

    курсовая работа [39,5 K], добавлен 06.02.2007

  • История, предпосылки развития, необходимость применения криптографии в жизни общества. Описание протоколов, цифровых подписей, алгоритмов, ключей. Криптоанализ, формальный анализ протоколов проверки подлинности и обмена ключами. Практическая криптография.

    дипломная работа [767,2 K], добавлен 23.12.2011

  • Аутентификация в Windows 2000. Преимущества аутентификации по протоколу Kerberos. Стандарты аутентификации по протоколу Kerberos. Расширения протокола и его обзор. Управление ключами, сеансовые билеты. Аутентификация за пределами домена, подпротоколы.

    курсовая работа [369,2 K], добавлен 17.12.2010

  • Модели нарушителей глобальной информационной системы Интернет. Классификация угроз в соответствии с IT-Baseline Protection Manual. Реализация DoS/DDos атак. Программная реализация Snort: установка, препроцессоры и структура модулей обнаружения и вывода.

    дипломная работа [509,5 K], добавлен 05.06.2011

  • Общая характеристика протокола ICMP, его назначение и формат сообщений. Анализ применимости протокола ICMP при переходе с набора протоколов IP v4 на набор IP v6. Свойства и принцип работы, сферы применения протоколов обмена маршрутной информацией.

    курсовая работа [210,8 K], добавлен 24.08.2009

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

    курсовая работа [586,6 K], добавлен 18.12.2011

  • Понятие безопасности данных. Базовые технологии сетевой аутентификации информации на основе многоразового и одноразового паролей: авторизация доступа, аудит. Сертифицирующие центры, инфраструктура с открытыми ключами, цифровая подпись, программные коды.

    курсовая работа [861,3 K], добавлен 23.12.2014

  • Краткая история развития криптографических методов защиты информации. Сущность шифрования и криптографии с симметричными ключами. Описание аналитических и аддитивных методов шифрования. Методы криптографии с открытыми ключами и цифровые сертификаты.

    курсовая работа [1,2 M], добавлен 28.12.2014

  • Комбинированное использование симметричного и асимметричного шифрования. Зависимость между открытым и закрытым ключами. Основные недостатки симметричного шифрования. Схема двухстороннего конфиденциального обмена. Концепция шифрования по алгоритму DES.

    презентация [1,4 M], добавлен 20.12.2012

  • Создание криптографического протокола аутентификации пользователя интернет-магазина на основе биометрии, посредством Adobe Dreamweaver CS3 на языке программирования PHP. Особенности, конструкциии криптосистем. Описание алгоритма хэширования MD5.

    реферат [802,9 K], добавлен 22.01.2012

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.