Практическая реализация алгоритма симметричного шифрования AES

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

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

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

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

Размещено на http://www.allbest.ru/

Размещено на http://www.allbest.ru/

Курсовая работа

Практическая реализация алгоритма симметричного шифрования AES

Введение

В рамках курсового проекта по дисциплине «Компьютерные системы защиты информации» была поставлена следующая задача: «Практическая реализация алгоритма симметричного шифрования AES, его описание, изучение его достоинств и недостатков».

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

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

1. Описание симметричного алгоритма AES

1.1 История возникновения AES (алгоритма симметричного шифрования)

В 1998 году NIST (National Institute of Standards and Technology) объявили конкурс по созданию алгоритма симметричного шифрования, под названием Advanced Encryption Standard сокращено AES. Этот алгоритм должен был стать новым стандартом USA на замену уже устаревшему стандарту Digital Encryption Standard сокращено DES, принятым в 1977 году. Причиной для смены стандарта являлась малая длина ключа DES которая составляла 56 бит, что позволяло злоумышленникам взламывать DES применяя простой метод перебора ключей. Так же проблему вызывала архитектура DES которая была направленна на аппаратную реализацию, что не позволяла программным реализациям получать достаточную скорость быстродействия в связи с нехватками ресурсов. Хотя и модификация TripleDES обладала достаточно большой длиной ключа, но была еще медленнее чем классический DES [1].

2 января 1997 года NIST объявляет о намерении выбрать новый алгоритм взамен устаревшей DES. 12 сентября 1997 г. был объявлен конкурс. Было разрешено представлять свой алгоритм любым организациям и группам исследователей. Все параметры для кандидатов были в свободном доступе, но NIST потребовало предварительного объявления основных принципов работы алгоритмов. В этот раз NIST решил не повторять ошибки, которые были при выборе DES, которые заключались в закрытии публикации данных об исследовании алгоритмов-кандидатов. Основные требования к кандидатам на стандарт AES:

- метод шифрования должен быть блочным;

- длина обрабатываемого блока должна равняться 128 битам;

- размерность ключей должна равняться 128, 192 или 256 битам.

Дополнительные рекомендации для конкурсантов:

- ориентироваться на 32-разрядные процессоры.

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

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

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

2 октября 2000 объявили победителя конкурса, им стал алгоритм Rijndael. Сразу после завершения конкурса была начата процедура стандартизации и уже 28 февраля 2001 года был опубликован готовый проект, а 26 ноября 2001 года AES был принят как новый стандарт.

AES не является чистым алгоритмом Rijndael, т.к. у классического алгоритма Rijndael поддерживается больший диапазон длин ключей и блоков. В AES же размер ключей фиксированный и равен 128 бит, а в Rijndael размер возможных ключей составляет промежуток - от 128 до 256 бит, с шагом 32 бита. В AES фиксированная длина блоков, которая составляет 16 байт, а в Rijndael дается возможность выбирать размер блока самостоятельно.

Rijndael - это компактный алгоритм с простой математической частью и высокой скоростью исполнения. Данный алгоритм показал хорошую стойкость к атакам, при которых пытались декодировать зашифрованные данные, анализируя внешние параметры алгоритма, куда входит время выполнения и уровень энергопотребления. В данном алгоритме возможно распараллеливание процессов, что позволяет с лёгкостью обеспечивать полное использование процессорных ресурсов. AES это алгоритм Rijndael с ключом в 128 бит и блоком данных 16 байт.

1.2 Шифрование

Принцип работы шифрования алгоритма AES и его основные функции

В алгоритме AES используются определенные функции как для шифрования, так и для дешифрования, основные функции алгоритма шифрования приведены в таблице 1.

При шифровании алгоритмом AES необходим секретный ключ размером 128 бит, ключ представляется как матрица размерностью 4x4 байта. В начале происходит разбитие текста на блоки размерность 128 бит, если в последнем блоке не хватает данных для его полного заполнения, то свободное место забивается нулями [2].

Двумерный массив размерность 16 байт в который заносят по очереди блоки с начальными данными обычно обозначается как state[a] [b]. Шифрование этих блоков происходит независимо друг от друга что позволяет распараллеливать эти процессы и конечный результат записывается в один массив.

Для шифрования каждого блока требуется как минимум 10 раундов, в каждый раунд входят следующие функции:

- KeyExpansion.

- AddKey

- SubBytes

- ShiftRows

- MixColumns

- AddRoundKey

Сначала из основного ключа с помощью функции KeyExpansion генерируются раундовые ключи, каждый раундовый ключ используется один раз в одном раунде. После происходит суммирование данных с основным ключом в функции AddRoundKey. После выполнения функции AddRoundKey программа уходит в цикл пока счетчик не сравняется с заранее установленным количеством раундов для данного случая. В теле цикла вызывается функция замены байтов SubBytes, затем циклический сдвиг строк ShiftRows, перемешивание MixColumns, и суммирование с раундовым ключом AddRoundKey. В последнем 10 раунде функция MixColumns пропускается, наглядный пример работы алгоритма шифрования представлен в бок схеме Рисунок 1.

Таблица 1. Функции алгоритма AES

Рисунок 1. Блок схема алгоритма шифрования AES

Подробное описание функций алгоритма шифрования AES

Расширение ключа KeyExpansion

Для создания, раундовых ключей, которые используются в функции AddRoundKey, алгоритм AES берет секретный ключ и производит расширение ключа [3].

Расширенный ключ состоит из 16 байт (четыре байта на слово), обозначаемых ниже как wi, где i находится в диапазоне [0..44]. Полная длина расширенного ключа для всех раундов программы составляет 1408 бит, на каждый раунд дается ключ длиной 128 бит. Для расширения базового ключа используется массив констант, который называется Rcon. Нумерация массива начинается от 1 до 256+3. Их значения определяются следующим образом:

Rcon1 = 1;

Rconk = 2 * Rconk-1 = 2^k-1, для k = 2, 3,… 255;

Rconk = 0, для k = 256, 257, 258;

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

1) Основной ключ шифрования копируются в первые четыре слова расширенного ключа.

2) Для получения остальных частей ключа происходит их генерация следующим образом:

- если i кратно 4, то wi = SubBytes (RotByte(wi-1)) + Rcon (i/4);

- если i не кратно 4, то wi = wi-4 + wi-1.

Преобразование AddRoundKey и AddKey

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

state[j] [i] ^= RoundKey[j] [i]

Преобразование SubBytes

Функция SubBytes производит поочередную замену элементов матрицы с исходными данными на элементы из фиксированной матрицы S-BOX табл. 2. Основной целью этой замены является усложнение линейного дифференциального криптоанализа.

Таблица 2.Таблица подстановки S-Box

Преобразование ShiftRows

Функция ShiftRows производит побайтовый сдвиг строк влево по следующему алгоритму: первая строка не изменяется, вторая сдвигается на 1 байт влево, третья строка на 2 байта, а четвертая на 3 байта[4].

Преобразование MixColumns

При MixColumn столбцы Состояния рассматриваются как многочлены над GF(28) и умножаются по модулю x^4+1 на фиксированный многочлен a(x):

Этот многочлен - взаимно простой с x^4+1 и поэтому обратим.

1.3 Дешифрование

Все преобразования, которые были произведены при шифровании однозначны и, в следствии чего, имеют обратное преобразование, чтобы выполнить дешифрование для алгоритма AES.

Порядок обратного преобразования выглядит так: Производится расширение основного ключа KeyExpansion, после чего программа уходит в цикл до полного прохождения 9 раундов из 10. В которых выполняются следующие функции по порядку:

1. AddRoundKey - в данной функции происходит суммирование обрабатываемых данных с раундовым ключом.

2. InvMixColumns - в этой функции происходит перемешивание столбцов state обратная функции MixColumns.

3. InvShiftRows - данная функция производит обратный функции ShiftRows циклический сдвиг строк state.

4. InvSubBytes - в этой функции происходит замена байтов state по таблице замен для дешифрования.

После успешного прохождения девяти раундов программа выходит из цикла и исполняет оставшиеся функции для последнего раунда:

4.1. AddRoundKey

4.2. InvShiftRows

4.3. InvSubBytes

Программа выполняет данные процедуры со всеми блоками исходных данных после чего объединяет их в выходном файле[5].

Подробное описание функций алгоритма дешифрования AES.

Преобразование InvMixColumns

Преобразование InvMixColumns является обратным для преобразования MixColumns и преобразование в этой функции подобно самой функции MixColumns, где каждый столбец умножается на особый многочлен d(x) который определяется:

('03'x^3+'01'x^2+'01'x+'02')Д d(x)='01',

d(x)='0B'x^3+'0D'x^2+'09'x+'0E'

Преобразование InvShiftRows

Преобразование InvShiftRows является обратным для ShiftRows. В данном случае байты 2,3 и4 ряда сдвигаются в право. Вторая строка (нумерация строк начинается с 0) смещается на 1 байт, в третей строке - на 2 байта, а в четвертой - на 3 байта [6].

Преобразование InvSubBytes

Преобразование InvSubBytes тоже выполняет замену байт но уже с помощью обратной таблицы замен, называемой InvSbox. Обратная таблица замен приведена в Таблице 3.

Таблица 3. Таблица замен InvSbox

2. Преимущества и недостатки симметричного алгоритма AES

2.1 Недостатки алгоритма DES?

Предшественником алгоритма AES являлся алгоритм DES который разработанный фирмой IBM и утверждённый правительством США в 1977 году как официальный стандарт. Проблемы алгоритма DES начались в 1973 г., когда Национальным бюро стандартов (National Bureau of Standards, NBS, предшественник NIST) были объявлены поиски алгоритма для стандарта DES. Предварительный стандарт было поручено проверить Агентству национальной безопасности (National Security Agency, NSA). Когда компания IBM предложила свой алгоритм шифрования под названием Lucifer в качестве стандарта DES. NSA рекомендовало внести два изменения, которые уже были одобрены NBS.

Одно из изменений, которые предлагали NSA заключалось в изменении размера ключа со 128 как было в Lucifer, до 56 бит. Проблема этого изменения заключалась в том, что в 1977 г. математики Уaйтфилд Диффи и Мapтин Хеллмaн, которыми был разработан алгоритм открытых ключей, который носил название Диффи-Хеллмaнa, объявили, что могут создать машину, которой под силу разгадать все ключи для данного алгоритма.

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

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

К сожалению, уже к 1990 г. Были сильно снижены затраты на машину для взлома DES. После чего в 1997 г. Группа добровольцев смогла взламывать DES в течении длительного времени. На следующий год уже была представлена полноценная машина с возможность взламывать один ключ каждые 5 дней. В итоге было решено заменить алгоритм DES.

2.2 Выбор AES

После демонстрации успешного взлома DES, NIST (Национальный институт стандартов и технологий США) решает заменить этот алгоритм и начинает поиски и анализ нового стандарта. Были опубликованы все данные o тестировании кандидатов на роль AES не относящиеся к секретным и выдвинуты требования авторам алгоритмов сообщить o базовых принципах построения, используемых в них констант, таблиц [2].

На роль AES был представлен 21 кандидат, из них шесть не соответствовали начальным требованиям, 10 были отсеяны уже после первого этапа проверки. В августе 1999 г. было объявлено пять финалистов конкурса на роль AES.

1. MARS

2. RC6 (tm)

3. Twofish

4. Serpent

5. Rijndael

Все пять алгоритмов являлись блоковыми шифраторы, у всех предусматривалось проведение нескольких раундов. Основными характеристиками при выборе являлись следующие девять параметров: две касались защиты (общий уровень защиты и защищённость реализации), гибкость, a остальные были направленны на эффективность реализации. В конце итогового тестирования NIST были присвоил оценки финалистам - «отлично», «хорошо» или «удовлетворительно» - по разным критериям. Эти оценки представлены на Рисунке 2 и Рисунке 3 различным числом, от одного до трёх, где один соответствует минимальной оценке, a три - максимальной.

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

К примеру, при шифровании 128-битным ключом Rijndael выполняет 10 раундов. После проведения анализа уровня защиты Rijndael было выявлено что при выполнении количества раундов меньше восьми стойкость алгоритма была недостаточной. По этой методике так же были проверены остальные участники. По результатам проведенных опытов было обнаружено, что Rijndael для устойчивости к атакам хватает 8 раундов. Специалисты NIST решили, что данный алгоритм обладает достаточным запасом прочности, хотя другие кандидаты имеют даже больший запас прочности.

Для оценки производительности были проведены проверки реализаций как программными, так и аппаратными методами. При проверке реализаций программными методами были рассмотрены реализации на C, Java и смарт-карт на базе ARM, помимо 32 битных реализаций были и 64, так же проверки были проведены на как на 8 разрядных процессорах, так и на процессорах для обработки цифровых сигналов. На Рисунке 2 графически показаны оценки всех финалистов на уровне проверки по программной реализации. При анализе алгоритмов, предназначенных для устройств с ограниченными ресурсами, было использованы: смарт-карты c 8-paзpядным процессором и процессором Motorola 6805, чья оперативная память составляла всего 120 байт.

Рисунок 2. Результаты оценочных проверок на C, Java и на смарт-картах на базе ARM

Специалистами NIST также были проанализированы технические характеристики финалистов, способные повлиять на их производительность (cм. Рисунок 3). В основном оценивались затраты ресурсов на шифрование и дешифрование, a также возможность распараллеливания алгоритмов, которая позволяла значительно повышать скорость обработки данных. Еще одним из важных параметров было количество затрат на смену ключей - ведь большая часть алгоритмов шифрования проводит некоторую предварительную процедуру обработки ключа прежде, чем происходит шифрование и дешифрование. Этот параметр очень важен для устройств, которые осуществляют шифрование для большого количества соединений, например, шлюз IPSec или защищённый сервер Web.

Рисунок 3. Результаты по исследованиям затрат на шифрование и дешифрование, возможность распараллеливания алгоритма для повышения скорости обработки

Для более подробного рассмотрения преимуществ выбранного алгоритма Rijndael рассмотрим всех претендентов в AES.

MARS

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

RC6

RC6 - простои алгоритм c неплохим запасом прочности. Но как и в MARS, RC6 используют переменное чередование с умножением из за чего его очень трудно защищать от атак направленных на реализацию, но легче чем тот же MARS.

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

SERPENT

Основное отличие алгоритма Serpent от победителя Rijndael заключается в выполнении более простых раундов с большим количеством чем Rijndael с его более сложными раундами. Из-за своей просты и надежнсти в архитектуре Serpent напоминает DES т.к. он опирается на те же хорошо известные операции. В следствии чего оценить надёжность Serpent оказалось намного проще, и после изучения этого алгоритма по методике c сокращённым числом раундов стало понятно, что он обладает достаточно большим запасом прочности. Serpent является одним из тех алгоритмов, которые проще всего защитить от атак на реализацию.

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

Serpent предлагал самое лучшее сочетание простоты и запаса прочности, чем Rijndael, но уступил из-за очень низкой программной реализации.

TWOFISH

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

Изучение вариантов Twofish c уменьшенным количеством раундов показало, что он обладает достаточно высоким уровнем стойкости. Хотя, как и в случае c MARS, его специфическая структура породила определённые сомнения в качестве этих исследований. Так же отмечалось, что из-за сложности проанализировать его более подробно в отведённые сроки оказалось очень сложно.

Хотя данный алгоритм и уязвим для атак на реализацию, его можно модифицировать, чтобы он был способен противостоять некоторым видам атак. В целом алгоритм показал среднюю производительность. По итогам тестов производительность программной реализации показала результат ниже среднего a время, затраченное на предварительные обработки ключа самым большим. Аппаратная реализация выдала довольно средний результат. В итоге Twofish не был выбрал из-за его высокой сложности алгоритма и средним показателям производительности.

RIJNDAEL

Rijndael - оказался самым быстрым и компактным алгоритмом c простой математической частью, благодаря чему он оказался простым для анализа стойкости, и не вызывал никаких подозрений со стороны NIST. Но это так же облегчало подготовку хакеров к взлому алгоритма ведь им требовалось изучить небольшой математический аппарат - и если в Rijndael имелись не видные на первый взгляд слабые части, то рано или поздно их кто-нибудь мог обнаружить. Атаки на версию c малым количеством раундов показали, что Rijndael не имеет большого запаса прочности, как другие кандидаты, a увеличение числа раундов замедляло его работу.

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

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

NIST приняли решение и остановили свой выбор на Rijndael, так как он сочетал в себе как простоту так и высокую скорость работы. Хотя он и обладал меньшим запасом прочности по сравнению с другими финалистами, но это не несёт никакого практического риска. Если же сравнивать его с другими финалистами то на его реализацию уходило меньше ресурсов, но запаса его прочности вполне хватало для выполнения поставленных задач.

Исходя из всего выше изложенного можно утверждать что алгоритм Rijndael имеет следующие преимущества:

- структура алгоритма более надежная чем у предшественника.

- высокая производительность.

- хорошая как программная так и аппаратная реализация.

- относительная простота алгоритма.

- возможность распараллеливания задач.

- достаточная стойкость к взломам.

2.3 Уязвимость

Как и ожидалось, после принятия стандарта AES были присущи попытки взлома данного алгоритма. Кpиптoaнaлиз алгоритма AES обрел в основном следующие четыре направления:

Первое заключалось в усилении стандартных атак или же применение других известных видов атак к этому алгоритму. Одной из таких атак была атака методом бумеранга на 6-paундoвую версию алгоритма где использовался 128-битный ключ, для для его выполнения требовалось 239 открытых текстов, 271 шифрованных текстов c адаптивным выбором и 271 операций шифрования.

Второе направление заключалось в различных методах кpиптoaнaлизa на связанных ключах, были предложены следующие вида атак:

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

* данный метод заключался в комбинировании атак связанных ключей и метода бумеранга. Атака производится при наличии следующих данных:

- для 9-paундoвый AES-192 требуется 279 выбранных открытых текстов, каждый из которых шифруется на 256 связанных ключах, выполнением 2125 операций шифрования;

- для 10-paундoвый AES-256 требуется 2114,9 выбранных открытых текстов (включая зашифрованные на 256 связанных ключах) и 2171,8 операций шифрования.

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

Хотя и перечисленные варианты атак на связанных ключах мало эффективны многие начинают опасаться, что из-за довольно малого числа раундов алгоритм AES-192 может быть вскрыт раньше, чем рассчитывали в NIST изначально, ведь уже 10 из 12 раундов алгоритма уже подвержены атаке данного типа.

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

* Найдена линейность в таблице замен Rijndael. Хотя, как и при других похожих работах, практического способа для реализации взлома с использованием данного свойства не было продемонстрировано.

* Показано, что вскрытие алгоритма AES эквивалентно решению системы квадратичных уравнений в конечном поле GF(28).

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

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

Заключение

В результате выполнения курсового проекта по дисциплине «Компьютерные системы защиты информации» на тему «Практическая реализация алгоритма симметричного шифрования AES, его описание, изучение его достоинств и недостатков» мною были изучены:

- структура алгоритма,

- история создания алгоритма AES,

- методы проверки на принятие стандарта алгоритма AES,

- методы реализации алгоритма AES,

- его преимущества и недостатки.

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

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

В дальнейшем курсовой проект может быть развит до дипломного путем:

- доработки интерфейса.

- повышения быстродействия.

- повышения эффективности.

- добавления новых возможностей программы.

Литература

1. Зензин О.С. Стандарт криптографической защиты - AES. Конечные поля/ О.С. Зензин, М.А. Иванов. - КУДИЦ-ОБРАЗ, 2002 -176с

2. Киселев Ю.А. Методические указания к лабораторной работе «Алгоритм AES пример современного симметричного криптопреобразования по курсу «Криптографические методы защиты информации» составил Ю.А. Киселев,

[и др.]; Екатеринбург, 2016, - 29 с.

3. Алгоритм шифрования AES для самых маленьких [Электронный ресурс] // (http://teh-box.ru/programming/algoritm-shifrovaniya-aes-dlya-samyx-malenkix.html)

4. Описание стандарта шифрования AES (Advanced Encryption Standard, улучшенный стандарт шифрования) [Электронный ресурс] // (https://software.intel.com/ru-ru/articles/aes-advanced-encryption-standard)

5. Алгоритм Rijndael (стандарт AES) [Электронный ресурс] // (http://kaf403.rloc.ru/POVS/Crypto/Rijndael.htm)

6. Алгоритм AES [Электронный ресурс] //

(http://crypto.pp.ua/2010/03/algoritm-aes-rijndael)

Приложение

Листинг программы

 // Cours work +Dlg.cpp: файл реализации

 //

#include «stdafx.h»

#include «Cours work +.h»

#include «Cours work +Dlg.h»

#include «afxdialogex.h»

#include <iostream>

#include <fstream>

using namespace std;

#ifdef _DEBUG

#define new DEBUG_NEW

#endif

int size = 16;

unsigned char *skl = new unsigned char[size];

unsigned char *skm = new unsigned char[size];

 //Out - это массив, который содержит ключ для шифрования.

 // state - the array that holds the intermediate results during encryption.

 //State - массив, который содержит промежуточные результаты во время шифрования.

unsigned char in[16], out[16], state[4] [4];

 // Диалоговое окно CAboutDlg используется для описания сведений о приложении

class CAboutDlg: public CDialogEx

{

public:

CAboutDlg();

 // Данные диалогового окна

enum {IDD = IDD_ABOUTBOX};

protected:

virtual void DoDataExchange (CDataExchange* pDX); // поддержка DDX/DDV

 // Реализация

protected:

DECLARE_MESSAGE_MAP()

};

CAboutDlg:CAboutDlg(): CDialogEx (CAboutDlg:IDD)

{

}

void CAboutDlg: DoDataExchange (CDataExchange* pDX)

{

CDialogEx: DoDataExchange(pDX);

}

BEGIN_MESSAGE_MAP (CAboutDlg, CDialogEx)

END_MESSAGE_MAP()

 // диалоговое окно CCoursworkDlg

CCoursworkDlg:CCoursworkDlg (CWnd* pParent /*=NULL*/)

: CDialogEx (CCoursworkDlg:IDD, pParent)

{

m_hIcon = AfxGetApp()->LoadIcon (IDR_MAINFRAME);

}

void CCoursworkDlg: DoDataExchange (CDataExchange* pDX)

{

CDialogEx: DoDataExchange(pDX);

}

BEGIN_MESSAGE_MAP (CCoursworkDlg, CDialogEx)

ON_WM_SYSCOMMAND()

ON_WM_PAINT()

ON_WM_QUERYDRAGICON()

ON_BN_CLICKED (IDOK, &CCoursworkDlg: OnBnClickedOk)

ON_BN_CLICKED (IDC_BUTTON_OPEN, &CCoursworkDlg: OnBnClickedButtonOpen)

ON_BN_CLICKED (IDC_BUTTON_SAVE, &CCoursworkDlg: OnBnClickedButtonSave)

ON_BN_CLICKED (IDC_BUTTON_KEY, &CCoursworkDlg: OnBnClickedButtonKey)

ON_BN_CLICKED (IDC_BUTTON_SHIFR, &CCoursworkDlg: OnBnClickedButtonShifr)

ON_BN_CLICKED (IDC_BUTTON_DESHIFR, &CCoursworkDlg: OnBnClickedButtonDeshifr)

END_MESSAGE_MAP()

 // обработчики сообщений CCoursworkDlg

BOOL CCoursworkDlg: OnInitDialog()

{

CDialogEx: OnInitDialog();

 // Добавление пункта «О программе…» в системное меню.

 // IDM_ABOUTBOX должен быть в пределах системной команды.

ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

ASSERT (IDM_ABOUTBOX < 0xF000);

CMenu* pSysMenu = GetSystemMenu(FALSE);

if (pSysMenu!= NULL)

{

BOOL bNameValid;

CString strAboutMenu;

bNameValid = strAboutMenu. LoadString (IDS_ABOUTBOX);

ASSERT(bNameValid);

if (! strAboutMenu. IsEmpty())

{

pSysMenu->AppendMenu (MF_SEPARATOR);

pSysMenu->AppendMenu (MF_STRING, IDM_ABOUTBOX, strAboutMenu);

}

}

 // Задает значок для этого диалогового окна. Среда делает это автоматически,

 // если главное окно приложения не является диалоговым

SetIcon (m_hIcon, TRUE); // Крупный значок

SetIcon (m_hIcon, FALSE); // Мелкий значок

 // TODO: добавьте дополнительную инициализацию

filename_save, filename_open, filename_key = «»;

fullfilename_save, fullfilename_open, fullfilename_key = «»;

return TRUE; // возврат значения TRUE, если фокус не передан элементу управления

}

void CCoursworkDlg: OnSysCommand (UINT nID, LPARAM lParam)

{

if ((nID & 0xFFF0) == IDM_ABOUTBOX)

{

CAboutDlg dlgAbout;

dlgAbout. DoModal();

}

else

{

CDialogEx: OnSysCommand (nID, lParam);

}

}

 // При добавлении кнопки свертывания в диалоговое окно нужно воспользоваться приведенным ниже кодом,

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

 // это автоматически выполняется рабочей областью.

void CCoursworkDlg: OnPaint()

{

if (IsIconic())

{

CPaintDC dc(this); // контекст устройства для рисования

SendMessage (WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc. GetSafeHdc()), 0);

 // Выравнивание значка по центру клиентского прямоугольника

int cxIcon = GetSystemMetrics (SM_CXICON);

int cyIcon = GetSystemMetrics (SM_CYICON);

CRect rect;

GetClientRect(&rect);

int x = (rect. Width() - cxIcon + 1) / 2;

int y = (rect. Height() - cyIcon + 1) / 2;

 // Нарисуйте значок

dc. DrawIcon (x, y, m_hIcon);

}

else

{

CDialogEx: OnPaint();

}

}

 // Система вызывает эту функцию для получения отображения курсора при перемещении

 // свернутого окна.

HCURSOR CCoursworkDlg: OnQueryDragIcon()

{

return static_cast<HCURSOR>(m_hIcon);

}

void CCoursworkDlg: OnBnClickedOk()

{

}

 /////////////////////////////////////////////////////////////////////////////////////////

 // Управление на форме

 /////////////////////////////////////////////////////////////////////////////////////////

void CCoursworkDlg: OnBnClickedButtonOpen() // открытие файла для чтения исходного текста

{

TCHAR Filter[] = _T («TXT Filters (*.txt)|*.txt||»); // фильтор для выбора формата файлов

SetCurrentDirectory (_T(«C:\\»)); // выбор начальной директории

CFileDialog fileDlg (TRUE, 0, 0, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, Filter); // Создание окна диолога

if (fileDlg. DoModal() == IDOK)

{

filename_open = fileDlg. GetFileName(); // Запись имени файла

fullfilename_open = fileDlg. GetPathName(); // Запись полного имени файла

}

ReadTxtFile(); // вызов функции для чтения файла

}

void CCoursworkDlg: OnBnClickedButtonSave() // выбор пути сохранения выходных значений

{

TCHAR Filter[] = _T («TXT Filters (*.txt)|*.txt||»); // фильтор для выбора формата файлов

SetCurrentDirectory (_T(«C:\\»)); // выбор начальной директории

CFileDialog fileDlg (TRUE, 0, 0, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, Filter); // Создание окна диолога

if (fileDlg. DoModal() == IDOK)

{

filename_save = fileDlg. GetFileName(); // Запись имени файла

fullfilename_save = fileDlg. GetPathName(); // Запись полного имени файла

}

}

void CCoursworkDlg: OnBnClickedButtonKey() // выбор ключа для работы программы

{

TCHAR Filter[] = _T («TXT Filters (*.txt)|*.txt||»); // фильтор для выбора формата файлов

SetCurrentDirectory (_T(«C:\\»)); // выбор начальной директории

CFileDialog fileDlg (TRUE, 0, 0, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, Filter); // Создание окна диолога

if (fileDlg. DoModal() == IDOK)

{

filename_key = fileDlg. GetFileName(); // Запись имени файла

fullfilename_key = fileDlg. GetPathName(); // Запись полного имени файла

}

OpenTxtFile(); // вызов функции для чтения ключа

}

void CCoursworkDlg: OpenTxtFile() // функция чтения ключа

{

memset (skm, 0, size);

int count = 0; // кол-во символов в файле

fstream t (fullfilename_key); // считывание в массив

for (int q = 0; q < size; q++)

{

t >> skm[q];

}

t.close();

}

void CCoursworkDlg: ReadTxtFile() // функция чтения из файла

{

memset (skl, 0, size);

int count = 0; // кол-во символов в файле

fstream f (fullfilename_open); // считывание в массив

for (int q = 0; q < size; q++)

{

f >> skl[q];

}

f.close();

}

void CCoursworkDlg: WriteTxtFile() // не пригодилось

{

}

void CCoursworkDlg: CloseTxtFile() // запись конечного результата преобразований

{

ofstream fout (fullfilename_save); // создаём объект класса ofstream для записи и связываем его с файлом cppstudio.txt

for (int e = 0; e < size; e++)

{

fout << out[e]; // запись строки в файл

}

fout.close(); // закрываем файл

}

 ////////////////////////////////////////////////////////////////////////////////////////////////////////

void CCoursworkDlg: OnBnClickedButtonShifr() // для шифрования

{

if ((filename_save!= «») && (filename_open!= «») && (filename_key!= «»)) // для проверки заполнения полей

{

DefiningInputParameters();

}

else

{

MessageBox (L «Выберите все параметры!»);

}

}

void CCoursworkDlg: OnBnClickedButtonDeshifr() // для дешифроваания

{

if ((filename_save!= «») && (filename_open!= «») && (filename_key!= «»)) // для проверки заполнения полей

{

Description();

}

else

{

MessageBox (L «Выберите все параметры!»);

}

}

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 // Таблицы и общие функции для шифрования и дешифрования

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#define Nb 4 // Количество столбцов, содержащих состояние в AES. Это константа в AES. Значение = 4

#define xtime(x) ((x<<1) ^ (((x>>7) & 1) * 0x1b)) //Xtime - это макрос, который находит произведение{02} и аргумент для xtime по модулю{1b}

int Nr = 10; // Количество раундов.

int Nk = 4; // Число 32-битных слов в ключе.

unsigned char RoundKey[240]; // Массив, в котором хранятся раундовые ключи.

unsigned char Key[32]; // Ключевой вклад в Программу AES

int getSBoxValue (int num) // таблица для замены при шифровании

{

int sbox[256] = {

 // 0 1 2 3 4 5 6 7 8 9 A B C D E F

0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, // 0

0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, // 1

0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, // 2

0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, // 3

0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, // 4

0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, // 5

0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, // 6

0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, // 7

0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, // 8

0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, // 9

0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A

0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B

0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C

0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D

0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E

0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; //F

return sbox[num];

}

 // Круглый массив постоянных слов, Rcon [i], содержит значения, заданные

 // x для мощности (i-1), являющейся степенью x (x обозначается как {02}) в поле GF (28)

 // Обратите внимание, что i начинается с 1, а не 0).

int Rcon[255] = {

0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,

0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,

0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,

0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,

0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,

0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,

0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,

0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,

0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,

0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,

0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,

0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,

0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,

0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,

0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,

0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb};

int getSBoxInvert (int num) // массив для обратной замены

{

int rsbox[256] =

{0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb

0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb

0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e

0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25

0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92

0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84

0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06

0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b

0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73

0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e

0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b

0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4

0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f

0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef

0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61

0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d};

return rsbox[num];

}

void CCoursworkDlg: KeyExpansion() // функция генерации раундовых ключей

{

int i, j;

unsigned char temp[4], k;

 // Ключ первого раунда - это сам ключ

for (i = 0; i<Nk; i++)

{

RoundKey [i * 4] = Key [i * 4];

RoundKey [i * 4 + 1] = Key [i * 4 + 1];

RoundKey [i * 4 + 2] = Key [i * 4 + 2];

RoundKey [i * 4 + 3] = Key [i * 4 + 3];

}

while (i < (Nb * (Nr + 1))) // Все остальные раундовые ключи находятся из предыдущих раундов.

{

for (j = 0; j<4; j++)

{

temp[j] = RoundKey[(i - 1) * 4 + j];

}

if (i% Nk == 0)

{

k = temp[0];

temp[0] = temp[1];

temp[1] = temp[2];

temp[2] = temp[3];

temp[3] = k;

temp[0] = getSBoxValue (temp[0]);

temp[1] = getSBoxValue (temp[1]);

temp[2] = getSBoxValue (temp[2]);

temp[3] = getSBoxValue (temp[3]);

temp[0] = temp[0] ^ Rcon [i / Nk];

}

else if (Nk > 6 && i% Nk == 4)

{

temp[0] = getSBoxValue (temp[0]);

temp[1] = getSBoxValue (temp[1]);

temp[2] = getSBoxValue (temp[2]);

temp[3] = getSBoxValue (temp[3]);

}

RoundKey [i * 4 + 0] = RoundKey[(i - Nk) * 4 + 0] ^ temp[0];

RoundKey [i * 4 + 1] = RoundKey[(i - Nk) * 4 + 1] ^ temp[1];

RoundKey [i * 4 + 2] = RoundKey[(i - Nk) * 4 + 2] ^ temp[2];

RoundKey [i * 4 + 3] = RoundKey[(i - Nk) * 4 + 3] ^ temp[3];

i++;

}

}

void CCoursworkDlg: AddRoundKey (int round) // функция добавления ключей

{

int i, j;

for (i = 0; i<4; i++)

{

for (j = 0; j<4; j++)

{

state[j] [i] ^= RoundKey [round * Nb * 4 + i * Nb + j];

}

}

}

 ////////////////////////////////////////////////////////////////////////////////////////////////////////

 // ШИФРОВАНИЕ ДЛЯ 128 БИТНОГО КЛЮЧА

 ////////////////////////////////////////////////////////////////////////////////////////////////////////

void CCoursworkDlg: DefiningInputParameters() // тело основной функции при шифровании

{

int i;

 // Копирование ключа и простого текста

for (i = 0; i<Nk * 4; i++)

{

Key[i] = skm[i];

in[i] = skl[i];

}

KeyExpansion(); // Функцию генерации ключей надо вызывать до шифрования

Cipher(); // функция шифрования файла по алгоритму AES

 // Вывести зашифрованный текст.

CloseTxtFile();

}

void CCoursworkDlg: SubBytes() // замена исходных данных в матрице на данные из заменной таблицы

{

int i, j;

for (i = 0; i<4; i++)

{

for (j = 0; j<4; j++)

{

state[i] [j] = getSBoxValue (state[i] [j]);

}

}

}

void CCoursworkDlg: ShiftRows() // сдвиг каждой строки влево на на определенное колличество байт

{

unsigned char temp;

 // Сдвиг первой строки на 1 столбц влево

temp = state[1] [0];

state[1] [0] = state[1] [1];

state[1] [1] = state[1] [2];

state[1] [2] = state[1] [3];

state[1] [3] = temp;

 // Сдвиг 2 строки на 2 влево

temp = state[2] [0];

state[2] [0] = state[2] [2];

state[2] [2] = temp;

temp = state[2] [1];

state[2] [1] = state[2] [3];

state[2] [3] = temp;

 // Сдвиг 3 строки на 3 влево

temp = state[3] [0];

state[3] [0] = state[3] [3];

state[3] [3] = state[3] [2];

state[3] [2] = state[3] [1];

state[3] [1] = temp;

}

 // ^ побитовое ИЛИ

void CCoursworkDlg: MixColumns() // Функция смешивания столбцов

{

int i;

unsigned char Tmp, Tm, t;

for (i = 0; i<4; i++)

{

t = state[0] [i];

Tmp = state[0] [i] ^ state[1] [i] ^ state[2] [i] ^ state[3] [i];

Tm = state[0] [i] ^ state[1] [i]; Tm = xtime(Tm); state[0] [i] ^= Tm ^ Tmp;

Tm = state[1] [i] ^ state[2] [i]; Tm = xtime(Tm); state[1] [i] ^= Tm ^ Tmp;

Tm = state[2] [i] ^ state[3] [i]; Tm = xtime(Tm); state[2] [i] ^= Tm ^ Tmp;

Tm = state[3] [i] ^ t; Tm = xtime(Tm); state[3] [i] ^= Tm ^ Tmp;

}

}

void CCoursworkDlg: Cipher() // основная функция шифрования

{

int i, j, round = 0;

for (i = 0; i<4; i++) // перенос входных данных в массив для обработки

{

for (j = 0; j<4; j++)

{

state[j] [i] = in [i * 4 + j];

}

}

 // Добавьте ключ первого раунда в состояние перед началом раундов

AddRoundKey(0);

for (round = 1; round<Nr; round++) // цикл для выполнения првых 9 раундов

{

SubBytes();

ShiftRows();

MixColumns();

AddRoundKey(round);

}

 // функции для последнего раунда:

SubBytes();

ShiftRows();

AddRoundKey(Nr);

for (i = 0; i<4; i++) // копирование результатта в массив для вывода результата

{

for (j = 0; j<4; j++)

{

out [i * 4 + j] = state[j] [i];

}

}

}

 ////////////////////////////////////////////////////////////////////////////////////////////////////////

 // ДЕШИФРОВАНИЕ ДЛЯ 128 БИТНОГО КЛЮЧА

 ////////////////////////////////////////////////////////////////////////////////////////////////////////

void CCoursworkDlg: Description()

{

 // Копирование ключа и CipherText

for (int i = 0; i < Nk * 4; i++)

{

Key[i] = skm[i];

in[i] = skl[i];

}

 // Процедуру Key-Expansion необходимо вызывать перед процедурой дешифрования.

KeyExpansion();

 // Следующий вызов функции расшифровывает CipherText с помощью ключа, используя алгоритм AES.

InvCipher();

CloseTxtFile();

}

void InvSubBytes() // функция обратной замены

{

int i, j;

for (i = 0; i<4; i++)

{

for (j = 0; j<4; j++)

{

state[i] [j] = getSBoxInvert (state[i] [j]);

}

}

}

void InvShiftRows() // функция сдвига строк в право

{

unsigned char temp;

 // Поворот первой строки 1 столбца вправо

temp = state[1] [3];

state[1] [3] = state[1] [2];

state[1] [2] = state[1] [1];

state[1] [1] = state[1] [0];

state[1] [0] = temp;

 // Второй

temp = state[2] [0];

state[2] [0] = state[2] [2];

state[2] [2] = temp;

temp = state[2] [1];

state[2] [1] = state[2] [3];

state[2] [3] = temp;

 // третьей

temp = state[3] [0];

state[3] [0] = state[3] [1];

state[3] [1] = state[3] [2];

state[3] [2] = state[3] [3];

state[3] [3] = temp;

}

 // Multiplty - это макрос, используемый для умножения чисел в поле GF (2 ^ 8)

#define Multiply (x, y) (((y & 1) * x) ^ ((y>>1 & 1) * xtime(x)) ^ ((y>>2 & 1) * xtime (xtime(x))) ^ ((y>>3 & 1) * xtime (xtime(xtime(x)))) ^ ((y>>4 & 1) * xtime (xtime(xtime (xtime(x))))))

void InvMixColumns() // функция для обратного смешифания столбцов

{

int i;

unsigned char a, b, c, d;

for (i = 0; i<4; i++)

{

a = state[0] [i];

b = state[1] [i];

c = state[2] [i];

d = state[3] [i];

state[0] [i] = Multiply (a, 0x0e) ^ Multiply (b, 0x0b) ^ Multiply (c, 0x0d) ^ Multiply (d, 0x09);

state[1] [i] = Multiply (a, 0x09) ^ Multiply (b, 0x0e) ^ Multiply (c, 0x0b) ^ Multiply (d, 0x0d);

state[2] [i] = Multiply (a, 0x0d) ^ Multiply (b, 0x09) ^ Multiply (c, 0x0e) ^ Multiply (d, 0x0b);

state[3] [i] = Multiply (a, 0x0b) ^ Multiply (b, 0x0d) ^ Multiply (c, 0x09) ^ Multiply (d, 0x0e);

}

}

 // InvCipher - основная функция дешифрования.

void CCoursworkDlg: InvCipher()

{

int i, j, round = 0;

for (i = 0; i<4; i++) // Копируем вход CipherText в массив состояний.

{

for (j = 0; j<4; j++)

{

state[j] [i] = in [i * 4 + j];

}

}

AddRoundKey(Nr); // добавление первого ключа

for (round = Nr - 1; round>0; round-)

{

InvShiftRows();

InvSubBytes();

AddRoundKey(round);

InvMixColumns();

}

 // Функции для последнего раунда:

InvShiftRows();

InvSubBytes();

AddRoundKey(0);

for (i = 0; i<4; i++) // копирование в выходной массив

{

for (j = 0; j<4; j++)

{

out [i * 4 + j] = state[j] [i];

}

}

}

Размещено на Allbest.ru


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

  • Симметричные криптосистемы как способ шифрования, в котором для шифрования и расшифровывания применяется один и тот же криптографический ключ. Разбор и реализация шифрования алгоритма: простая и двойная перестановка, перестановка "магический квадрат".

    курсовая работа [3,3 M], добавлен 11.03.2013

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

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

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

    лабораторная работа [335,9 K], добавлен 18.03.2013

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

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

  • Стандарт шифрования Advanced Encryption Standard как официальный стандарт правительства США для симметричного шифрования. Таблицы подстановки для S-Box и InvS-Box. Преобразование MixColumns, SubWord, RotWord. Процедура расширения ключа 128, 192, 256 бит.

    презентация [2,2 M], добавлен 12.12.2013

  • Реализация алгоритма DES и режимов шифрования для любой длины сообщения и любой длины ключа. Шифрование сообщений различной длины и ключа с замериванием времени и скорости шифрования. Реализация алгоритма RSA. Сохранение зашифрованного файла на диск.

    курсовая работа [398,4 K], добавлен 26.01.2010

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

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

  • Симметрическое шифрование как способ шифрования, в котором применяется один и тот же криптографический ключ. Функции стандартного диалогового окна открытия и сохранения файла. Характерная схема действий при генерации подписи. Цифровая подпись файла.

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

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

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

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

    контрольная работа [56,5 K], добавлен 26.09.2012

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