МИНОБРНАУКИ РОССИИ Федеральное государственное бюджетное образовательное учреждение высшего образования "МИРЭА - Российский технологический университет" РТУ МИРЭА Институт кибернетики Кафедра компьютерной и информационной безопасности УТВЕРЖДАЮ Заведующий кафедрой______________А.Н. Чесалин ЗАДАНИЕ на выполнение курсовой работы по дисциплине «Защита данных в системах специального назначения» Студент: Группа: КТСО-04-17 КТСО-05-17 1. Тема: Реализация шифра Вернама на с++. 2. Исходные данные: 1) Разработка программы на языке C++, реализующей алгоритм шифра Вернама 3. Краткая аннотация работы (перечень подлежащих разработке вопросов): 1) Проектирование пользовательского интерфейса 2) Реализация алгоритма шифра Вернама 3) Реализация пользовательского интерфейса и внедрение в него алгоритма 4. Срок представления к защите курсового проекта (работы): 10 декабря 2021 г. Руководитель курсовой работы __________________ А.В. Козлов С.В. Фомичев Задание принял к исполнению К.А. Мамин __________________ М.Э. Лукацкий МИНОБРНАУКИ РОССИИ Федеральное государственное бюджетное образовательное учреждение высшего образования "МИРЭА - Российский технологический университет" РТУ МИРЭА Институт Искусственного Интеллекта Кафедра компьютерной и информационной безопасности УТВЕРЖДАЮ Заведующий кафедрой______________А.Н. Чесалин ЗАДАНИЕ на выполнение курсовой работы по дисциплине «Защита данных в системах специального назначения» Студент: Группа: КТСО-04-17 КТСО-05-17 5. Тема: Реализация шифра Вернама на с++. 6. Исходные данные: 2) Разработка программы на языке C++, реализующей алгоритм шифра Вернама 7. Краткая аннотация работы (перечень подлежащих разработке вопросов): 4) Проектирование пользовательского интерфейса 5) Реализация алгоритма шифра Вернама 6) Реализация пользовательского интерфейса и внедрение в него алгоритма 8. Срок представления к защите курсового проекта (работы): 10 декабря 2021 г. Руководитель курсовой работы __________________ А.В. Козлов С.В. Фомичев Задание принял к исполнению М.Э. Лукацкий __________________ К.А. Мамин МИНОБРНАУКИ РОССИИ Федеральное государственное бюджетное образовательное учреждение высшего образования "МИРЭА - Российский технологический университет" РТУ МИРЭА Институт кибернетики Кафедра компьютерной и информационной безопасности КУРСОВАЯ РАБОТА по дисциплине «Защита данных в системах специального назначения» Тема курсовой работы: Реализация шифра Вернама на c++ Студент группы КТСО-04-17 С.В. Фомичев КТСО-05-17 К.А. Мамин М.Э. Лукацкий Руководитель курсовой работы: А.В. Козлов Работа представлена к защите «____»_________20__ г. __________________ (подпись студента) «Допущен к защите» «____»_________20__ г. __________________ (подпись руководителя) Москва 2021 МИНОБРНАУКИ РОССИИ Федеральное государственное бюджетное образовательное учреждение высшего образования "МИРЭА - Российский технологический университет" РТУ МИРЭА Институт Искусственного Интеллекта Кафедра компьютерной и информационной безопасности КУРСОВАЯ РАБОТА по дисциплине «Защита данных в системах специального назначения» Тема курсовой работы: Реализация шифра Вернама на c++ Студент группы КТСО-04-17 С.В. Фомичев КТСО-05-17 М.Э. Лукацкий К.А. Мамин Руководитель курсовой работы: А.В. Козлов Работа представлена к защите «____»_________20__ г. __________________ (подпись студента) «Допущен к защите» «____»_________20__ г. __________________ Москва 2021 (подпись руководителя) Москва 2021 Оглавление Введение......................................................................................................... 3 Глава 1. Теоретическая часть ....................................................................... 4 История ...................................................................................................... 4 Описание алгоритма ................................................................................. 5 Глава 2. Практическая часть ........................................................................ 7 Пример шифрования ................................................................................. 7 Пример дешифрования ............................................................................. 8 Алгоритм работы программы .................................................................. 8 Реализация программы ............................................................................. 9 Void unique(string& alpha, string& str) ................................................. 9 Int main()................................................................................................. 9 Class Vernam .......................................................................................... 9 Промежуточный вывод к программе .................................................... 10 Пример работы программы .................................................................... 10 Заключение .................................................................................................. 12 Список литературы ..................................................................................... 13 Приложение ................................................................................................. 14 Введение В данной курсовой работе будет рассмотрен способ шифрования текста шифром Вернама. Шифр Вернама – разновидность криптосистемы одноразовых блокнотов. В нём используется булева функция «исключающее или». Шифр Вернама является примером системы с абсолютной криптографической стойкостью. При этом он считается одной из простейших криптосистем. Работа на данном алгоритме шифрования реализована с применением языка C++. 3 Глава 1. Теоретическая часть История Шифр назван в честь телеграфиста Гильберта Вернама, который в 1917 году изобрёл, а в 1919 запатентовал систему автоматического шифрования телеграфных сообщений. Вернам не использовал понятие «исключающее или» в патенте, но реализовал именно эту операцию в релейной логике. Каждый символ в сообщении преобразовывался побитовым XOR (исключающее или) с ключом бумажной ленты. Джозеф Моборн (бывший тогда капитаном армии США, а впоследствии начальником корпуса связи) доработал эту систему так, чтобы последовательность символов на ключевой ленте была полностью случайной, поскольку в этом случае криптоанализ будет наиболее трудным. Вернам создал устройство, производящее указанные операции автоматически, без участия шифровальщика. Тем самым было положено начало так называемому «линейному шифрованию», когда процессы шифрования и передачи сообщения происходят одновременно. До той поры шифрование было предварительным, поэтому линейное шифрование существенно повышало оперативность связи. Не будучи шифровальщиком, тем не менее, Вернам верно заметил важное свойство своего шифра — каждая лента должна использоваться только один раз и после этого уничтожаться. Это трудноприменимо на практике — поэтому аппарат был переделан на несколько закольцованных лент с взаимно простыми периодами. 4 Описание алгоритма Криптосистема была предложена для шифрования телеграфных сообщений, которые представляли собой бинарные тексты, в которых открытый текст представляется в коде Бодо (в виде пятизначных «импульсных комбинаций»). В этом коде, например, буква «А» имела вид (1 1 0 0 0). На бумажной ленте цифре «1» соответствовало отверстие, а цифре «0» — его отсутствие. Секретный ключ должен был представлять собой хаотичный набор букв того же самого алфавита. Для получения шифротекста открытый текст объединяется операцией «исключающее или» с секретным ключом. Так, например, при применении ключа (1 1 1 0 1) на букву «А» (1 1 0 0 0) получаем зашифрованное сообщение (0 0 1 0 1): (1 1 0 0 0) ⊕ (1 1 1 0 1) = (0 0 1 0 1) Зная, что для принимаемого сообщения имеем ключ (1 1 1 0 1), легко получить исходное сообщение той же операцией: (0 0 1 0 1) ⊕ (1 1 1 0 1) = (1 1 0 0 0) Для абсолютной криптографической стойкости ключ должен обладать тремя критически важными свойствами: 1. Иметь случайное дискретное равномерное распределение; 2. Совпадать по размеру с заданным открытым текстом; 3. Применяться только один раз. Из-за особенностей работы шифра Вернама, необходимо, чтобы размер алфавита являлся степенью двойки (2, 4, 8, 16, 32, 64, 128 и т.д.). Пример, почему так необходимо: при операции XOR над буквами английского алфавита 𝑉 = 21 = 10101 и 𝐿 = 11 = 1011 получается результат 10101 ⊕ 01011 = 11110 = 30, при алфавите (𝐴 = 0, 𝐵 = 1, … , 𝑍 = 25) выходит за пределы этого алфавита. Чтобы избежать такой проблемы, необходимо иметь алфавит 00000 => 11111 = 32 символа. 5 Например, кодирование шифром Вернама по модулю 𝑚 = 26 (𝐴 = 0, 𝐵 = 1, … , 𝑍 = 25) и дополнительным расширением (1 = 26, . . . , 6 = 31): Табл. 1. Ключ: Пример шифровки Вернама EVTIQWXQVVOPMCXREPY Z Открытый текст: ALLSWELLTHATENDSWELL Шифротекст: E5Y1GS32GSO3IPUDSLTS Без знания ключа такое сообщение не поддаётся анализу. Даже если бы можно было перепробовать все ключи, в качестве результата мы получили бы все возможные сообщения данной длины плюс колоссальное количество бессмысленных дешифровок, выглядящих как беспорядочное нагромождение букв. Но и среди осмысленных дешифровок не было бы никакой возможности выбрать искомую. Когда случайная последовательность (ключ) сочетается с неслучайной (открытым текстом), результат этого (шифротекст) оказывается совершенно случайным и, следовательно, лишённым тех статистических особенностей, которые могли бы быть использованы для анализа шифра. 6 Глава 2. Практическая часть Шифр Вернама является симметричным, для шифровки и дешифровки используется одинаковый ключ и одинаковый алгоритм. Предположим, алфавит равен следующему: Табл. 2. Алфавит шифра Вернама A B C D E F G H I J K L M N O P 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Пример шифрования Предположим, мы хотим передать сообщение «hello ninja» Данное сообщение необходимо передать, используя алфавит стационарного диска: «hello ninja» => «HELLO NINJA» И уберем пробелы из-за отсутствия оных в алфавите: «HELLONINJA». В качестве ключа укажем, например «BIE = NINJAGO» «BIENINJAGO». Табл. 3. Шифровка Вернама, пример H E L L O N I N J A 0111 0100 1011 1011 1110 1101 1000 1101 1001 0000 B I E N I N J A G O 0001 1000 0100 1101 1000 1101 1001 0000 0110 1110 G M P G G A B N P O 0110 1100 1111 0110 0110 0000 0001 1101 1111 1110 Получаем в ответ «GMPGGABNPO». Итого, шифрованное сообщение BIENINJAGO – ключ для дешифровки. 7 будет: GMPGGABNPO, где Пример дешифрования Предположим, мы хотим дешифровать сообщение «GMPGGABNPO» с ключом «BIENINJAGO»: Табл. 4. Дешифровка Вернама, пример G M P G G A B N P O 0110 1100 1111 0110 0110 0000 0001 1101 1111 1110 B I E N I N J A G O 0001 1000 0100 1101 1000 1101 1001 0000 0110 1110 H E L L O N I N J A 0111 0100 1011 1011 1110 1101 1000 1101 1001 0000 Дешифрованное сообщение: HELLONINJA Алгоритм работы программы Сначала производится инициализация Машины Шифра Вернама – загружается алфавит из файла Алфавит.txt. По умолчанию там записана строка длиной 128 символов, содержащую по умолчанию все символы английского и русского алфавита, кроме букв «ёЁ». После этого, машина готова к работе. Так как алгоритм Шифра Вернама является симметричным, интерфейс программы весьма минималистичен: выводится алфавит программы, после чего запрашивается сообщение и ключ. Если вместо сообщения ввести «\0», будет запущен процесс смены алфавита, где у пользователя попросят ввести строку длиной, равной степени двойки. Если вместо сообщения ввести «0», программа завершится. 8 Процесс шифровки/дешифровки реализуется в рамках одной функции и распознается как шифровка. В начале шифровки идет быстрая проверка ключа – если ключ содержит недопустимые символы, они будут отброшены. После этого анализируется каждый символ исходного сообщения – если данный символ присутствует в алфавите, он шифруется и записывается в ответ, иначе символ пропускается. После шифровки, ответ возвращается пользователю. Реализация программы Программа состоит из двух функций: unique и main и класса Vernam. Void unique(string& alpha, string& str) Данная функция проходит по str и дописывает в alpha новые, не встречавшиеся ранее символы. Int main() Данная функция является точкой входа программы, где производится инициализация и цикл работы программы. Class Vernam Данный класс реализует машину для Шифра Вернама. В Vernam() загружается и устанавливается алфавит по умолчанию. Void init() задает алфавит для шифра с переходом буква -> число и число -> буква. String get_info() возвращает текущий алфавит машины. String ciph(string &message, string &key) шифрует message по key и возвращает новую шифрованную строку, не изменяя входные переменные. Void change_alphabet() задает новый алфавит, контролирует, чтоб он был длиной, равной степени двойки и устанавливает его. 9 Промежуточный вывод к программе Написанная программа выполняет главную задачу по шифровке сообщения шифром Вернама по заданному алфавиту. Максимальная сложность работы данной программы составляет O(m + n), где m – длина ключа, а n – длина сообщения. Программа отбрасывает любые повторяющиеся символы в алфавите и любые буквы ключа и сообщения, отсутствующие в алфавите. Пример работы программы Рис. 1. Запуск программы, Основное окно Рис. 2. Процесс смены алфавита Рис. 3. Шифрование Рис. 4. Дешифрование Рис. 5. Завершение работы программы 10 11 Заключение В ходе выполнения данной курсовой работы был рассмотрен алгоритм шифрования Вернама и написана программа, выполняющая данное шифрования в автоматическом режиме. В ходе тестовых запусков было установлено, что сообщение, зашифрованное с помощью данной реализации шифра Вернама можно расшифровать только при наличии идентичных алфавитов шифрования. 12 Список литературы 1. Шифр Вернама [Электронный ресурс]: статья – электронные данные – Википедия, свободная энциклопедия – Режим доступа: https://ru.wikipedia.org/wiki/%D0%A8%D0%B8%D1%84%D1%80_ %D0%92%D0%B5%D1%80%D0%BD%D0%B0%D0%BC%D0%B 0, свободный 2. Std::vector [Электронный ресурс]: документация – электронные данные – cppreference.com – Режим доступа: https://en.cppreference.com/w/cpp/container/vector, свободный 3. Std::unordered_map [Электронный ресурс]: документация – электронные данные – cppreference.com – Режим доступа: https://en.cppreference.com/w/cpp/container/unordered_map, свободный 4. Шифр Вернама [Электронный ресурс]: статья – электронные данные – КОД, журнал яндекс практикума – Режим доступа: https://thecode.media/vernam/, свободный 5. Работа с файлами в C++ [Электронный ресурс]: статья – электронные данные – PureCodeCpp – Режим https://purecodecpp.com/archives/2751, свободный 13 доступа: Приложение Табл. 5. 1. #include <iostream> 2. #include <fstream> 3. #include <cstdio> 4. #include <unordered_map> 5. #include <vector> 6. #include <string> 7. #define FILENAME "Алфавит.txt" 8. using namespace std; 9. void unique(string& alpha, string& str) 10. { 11. bool t; 12. for (auto i : str) 13. { 14. t = 1; 15. for (auto j : alpha) 16. if (i == j) 17. { 18. t = 0; 19. break; 20. } 21. if (t) 22. 23. alpha += i; } 24. } 25. class Vernam 26. { 27. unordered_map<char, unsigned int> Alphabet; 28. vector<char> Back; 29. string info; 30. public: 31. Vernam() 32. { 33. ifstream f(FILENAME); 34. getline(f, info); 35. if ((info.length() & (info.length() - 1)) != 0) 36. { 37. string shit = ""; 38. int t = 1; 39. while (t < info.length()) 40. { 41. while (shit.length() < t) 42. shit += info[shit.length()]; 43. t *= 2; 44. } 45. info = shit; 46. } 47. init(); 14 Код программы 48. } 49. void init() 50. { 51. Alphabet.clear(); 52. Back.clear(); 53. Alphabet = unordered_map<char, unsigned int>(info.length()); 54. Back = vector<char>(info.length()); 55. for (int i = 0; i < info.length(); i++) 56. { 57. Alphabet.insert(make_pair(info[i], i)); 58. Back[i] = info[i]; 59. } 60. } 61. string get_info() { return info; } 62. string ciph(string &message, string &key) 63. { 64. string ans = "", k = ""; 65. for (auto i : key) 66. if (k.length() > message.length()) 67. break; 68. else 69. if (Alphabet.count(i) > 0) 70. k += i; 71. if (k.length() == 0) 72. return "ERROR: KEY NOT PRESENT IN ALPHABET"; 73. for (int i = 0; i < message.length(); i++) 74. { 75. if (Alphabet.count(message[i]) == 0) 76. continue; 77. auto a = Alphabet.find(message[i]); 78. auto b = Alphabet.find(k[ans.length() % k.length()]); 79. ans += Back[a->second ^ b->second]; 80. } 81. return ans; 82. } 83. void change_alphabet() 84. { 85. string alpha, add; 86. unsigned int t; 87. cout << "Введите новый алфавит, по длине равный степени двойки:\n"; 88. getline(cin, add); 89. unique(alpha, add); 90. while ((alpha.length() & (alpha.length() - 1)) != 0) 91. { 92. t = 1; 93. while (t < alpha.length()) 94. 95. t <<= 1; printf("Алфавит: %s\nВведите еще %d символов:\n", alpha.c_str(), t - alpha.length()); 96. getline(cin, add); 15 97. unique(alpha, add); 98. } 99. info = alpha; 100. init(); 101. 102. } }; 103. 104. int main() 105. { 106. system("chcp 1251"); 107. string message, key; 108. Vernam machine = Vernam(); 109. while (1) 110. { 111. system("cls"); 112. printf("Текущий алфавит:\n%s\nДля смены алфавита введите \"\\0\"\nВведите сообщение: ", machine.get_info().c_str()); 113. getline(cin, message); 114. if (message == "0") 115. { 116. cout << "Получен сигнал на прерывание, машинв заглушена\n"; 117. break; 118. } 119. if (message == "\\0") 120. { 121. machine.change_alphabet(); 122. continue; 123. } 124. cout << "Введите ключ: "; 125. getline(cin, key); 126. message = machine.ciph(message, key); 127. printf("Шифр Вернама: %s\n", message.c_str()); 128. system("pause"); 129. 130. } } 16