Файл: Методы кодирования данных (позволяющие выполнять шифрование).pdf

ВУЗ: Не указан

Категория: Курсовая работа

Дисциплина: Не указана

Добавлен: 06.04.2023

Просмотров: 412

Скачиваний: 3

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Листинг 4. Исходный код методов шифрования и дешифрования

private string encrypt(int symbol, BigInteger keyE, BigInteger keyN)

{

return BigInteger.ModPow(symbol, keyE, keyN).ToString();

}

private int decrypt(int symbol, BigInteger keyD, BigInteger keyN)

{

return (int)(BigInteger.ModPow(symbol, keyD, keyN));

}

private string textEncrypt(string text, BigInteger e, BigInteger n)

{

string eText = "";

foreach (var symbol in text)

eText += encrypt(symbol, e, n) + this.blockSep;

return eText;

}

private string textDecrypt(string text, BigInteger d, BigInteger n)

{

string[] arr = text.Split(this.blockSep);

string dText = "";

foreach (var symbol in arr)

if (symbol != string.Empty)

dText += Convert.ToChar(decrypt(int.Parse(symbol), d, n));

return dText;

}

Для работы с длинными числами здесь используется тип данных BigInteger. Этот целочисленный тип данных отображается на тип System.Numerics.BigInteger библиотеки Microsoft .NET Framework, позволяющий записывать и обрабатывать целые числа практически неограниченной длины. Для данных типа BigInteger реализованы арифметические операции сложения, вычитания, умножения и деления. Операция деления, в отличие от других целочисленных типов данных, возвращает не вещественное значение, а результат целочисленного деления, имеющий тип BigInteger. Метод класса BigInteger.ModPow(p, q, k) возвращает остаток от целочисленного деления на k значения p в степени q.

Функция generatePQ генерирует значения и , а также вычисляет соответствующие значения функции Эйлера, открытого и закрытого ключей.

Простые числа выбираются из диапазона (10000, 20000) – генерируется пара чисел, каждое из которых проверяется на простоту при помощи алгоритма Миллера-Рабина с 10 раундами до тех пор, пока оба выбранных числа не окажутся простыми. Исходный код функции представлен в листинге 5.

Листинг 5. Исходный код функции генерации p и q

private void getPrimeNum(Random rnd, out int n1, out int n2)

{

int firstNumber;

int secondNumber;

do

{

firstNumber = rnd.Next(10000, 20000);

secondNumber = rnd.Next(10000, 20000);

}

while (!Utilities.MillerRabin(firstNumber, 10) || !Utilities.MillerRabin(secondNumber, 10));

n1 = firstNumber;

n2 = secondNumber;

}

Набор методов для алгоритма RSA получения открытого и закрытого ключей, описанного в разделе 1, приводится в листинге 6. Функция NOD вычисляет НОД (Наибольший Общий Делитель) для проверки взаимной простоты в методе нахождения числа e. Вызов методов осуществляется внутри функции generatePQ, которая инициализирует поля класса RSA значениями для открытого и закрытого ключей.

Листинг 6. Набор методов для получения открытого и закрытого ключей в соответствии с алгоритмом RSA

// 2. найти модуль

private BigInteger getN(int p, int q)

{

return p * q;

}

// 3. найти значение функции Эйлера fi


private BigInteger getFi(int p, int q)

{

return (p - 1) * (q - 1);

}

// 4. выбрать число е, взаимное простое с fi

private BigInteger getPrime(Random rnd, BigInteger fi)

{

BigInteger e = rnd.Next(1, Math.Abs((int)fi));

do

{

if (NOD(e, fi) == 1)

break;

else e++;

} while (true);

if (e >= fi)

{

e--;

do

{

if (NOD(e, fi) == 1)

break;

else e--;

} while (true);

}

return e;

}

// 5. найти d при помощи расширенного алгоритма Евклида

private BigInteger getD(BigInteger e, BigInteger fi)

{

BigInteger i = fi, v = 0, d = 1;

while (e > 0)

{

BigInteger t = i / e, x = e;

e = i % x;

i = x;

x = d;

d = v - t * x;

v = x;

}

v %= fi;

if (v < 0)

v = (v + fi) % fi;

return v;

}

Полный исходный код программы приведен в приложении 1.

Тестовый пример, приведенный в данном подразделе, можно рассматривать как руководство пользователя. Для запуска программы достаточно запустить файл RSAForm.exe. Программа корректно работает в MS Windows 7/8/10. Установка не требуется.

Пример шифрования при помощи ввода текста в верхнее текстовое и нажатия кнопки «Зашифровать» приведен на рисунке 4.

Рисунок 4 – Шифрование текста с генерацией p и q

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

Рисунок 5 – Сообщение об ошибке при попытке ручного ввода чисел

Функции приложения могут быть проверены без ввода секретного ключа. Для этого необходимо, не меняя результат шифрования текста в нижнем текстовом поле, нажать кнопку «Расшифровать» в левой верхней части окна (рисунок 6). Результат представлен на рисунке 7.

Рисунок 6 – Выбор дешифрования только что зашифрованного текста

Рисунок 7 – Результат дешифрования только что зашифрованного текста

На рисунке 8 приведен результат шифрования при помощи значений p и q, заданных вручную.

Рисунок 8 – Шифрование текста при помощи заданных вручную значений p и q

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

Рисунок 9 – Результат дешифрования при помощи закрытого ключа


ЗАКЛЮЧЕНИЕ

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

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

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

В ходе выполнения работой было выполнено ознакомление с понятием шифрования с открытым ключом и подробно рассмотрены алгоритмы RSA и Диффи-Хеллмана. Также было выполнено ознакомление с ключевыми понятиями теории циклических избыточных кодов, подробно рассмотрен алгоритм CRC, сформулированы алгоритмы построения таблицы и вычисления контрольной суммы по этому алгоритму. Также было выполнено обоснование выбора языка программирования и среды разработки, итогом которого стала реализация алгоритмов RSA и CRC на языке высокого уровня C# в виде оконных приложений Windows.Forms в среде Visual Studio 2019.

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

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ

  1. Аршинов М. Н. Коды и математика / М.: Наука, 1983. – 257 с.
  2. Буркатовская Ю. Б. Быстродействующие алгоритмы деления полиномов в арифметике по модулю два / Ю. Б. Буркатовская, А. Н. Мальчуков, А. Н. Осокин // Изв. Томск. политехн. ун-та. – 2006. – № 1 (309). – с. 19–24.
  3. Демидович, Е.М. Основы алгоритмизации и программирования. Учебное пособие / Е. М. Демидович. - 2-е изд., испр. и доп. - СПб. : БХВ - Петербург, 2008. - 440 с.
  4. Документация по семейству продуктов Visual Studio [Электронный ресурс]. – Режим доступа: https://docs.microsoft.com/ru-ru/visualstudio/?view=vs-2019 – (Дата обращения – 25.04.2020).
  5. Коробейников А. Г, Ю.А.Гатчин. Математические основы криптологии. Учебное пособие / СПб: СПб ГУ ИТМО, 2004. – 106 с.
  6. Коутинхо С. Введение в теорию чисел. Алгоритм RSA / М.: Постчаркет, 2001. – 328 с.
  7. Мыцко Е. А. Особенности программной реализации вычисления контрольной суммы CRC32 на примере PKZIP, WINZIP, ETHERNET / Е. А. Мыцко, А. Н. Мальчуков // Вестн. науки Сибири. – 2011. – № 1 (1). – с. 279–282.
  8. Олифер В. Г. Компьютерные сети. Принципы, технологии, протоколы / В. Г. Олифер, Н. А. Олифер. ‒ СПб.: Питер, 2008. ‒ 958 с.
  9. Темников Ф. Е. Теоретические основы информационной техники: учеб. пособие. – 2-е изд., испр. и доп. / Ф. Е. Темников, В. А. Афонин, В. И. Дмитриев. – М.: Энергия, 1979. – 512 с.
  10. Яковлев В. В. Оценка влияния помех на производительность протоколов канального уровня / В. В. Яковлев, Ф. И. Кушназаров // Изв. Петерб. гос. ун-та путей сообщения. – СПб.: ПГУПС, 2015. – Вып. 1 (42). – с. 133–138.
  11. Arthur-Durett K. The Weakness Of Winrar Encrypted Archives To Compression Side-channel Attack, Open Access Theses, Purdue University, 2014
  12. C# docs [Электронный ресурс]. – Режим доступа: https://docs.microsoft.com/ru-ru/dotnet/csharp/ – (Дата обращения – 19.04.2020).
  13. Halsall F. Data communications, computer networks and open systems / F. Halsall. – Addison-Wesley: Pearson Education, 1996. ‒ 907 р.
  14. Hamilton J. Creating ZIP Files with ODS, Division of Research, Kaiser Permanente, Oakland, California, Paper 131-2013, SAS Global Forum 2013
  15. Ross N. W. A Painless guide to CRC error detection algorithms / N. W. Ross. – 16 Lerwick Avenue, Hazelwood Park, 5066. – Australia, 1993. – URL: http://www.ross.net/crc/download/crc_v3.txt (дата обращения: 18.04.2020).
  16. Systems Engineering and Software Development Life Cycle Framework [Электронный ресурс]. – Режим доступа: http://opensdlc.org/mediawiki/index.php?title=Main_Page – (Дата обращения – 25.04.2020).
  17. Tar Vs Zip VsGz: Difference And Efficiency [Электронный ресурс] / URL: https://itsfoss.com/category/linux/ (Дата обращения: 22.04.2020)
  18. WinRAR Download and Support [Электронный ресурс] / URL: http://www.win-rar.com/rarproducts.html (Дата обращения: 24.04.2020)
  19. ZIP Format Specification [Электронный ресурс] / URL: http://www.pkware.com/documents/casestudies/APPNOTE.TXT (Дата обращения: 23.04.2020)

Приложение 1. Исходные коды программ

Листинг А1. RSA.cs

using System;

using System.Collections.Generic;

using System.Numerics;

namespace RSAForm

{

public class RSA

{

private char blockSep = '*';

private static Random rnd;

private BigInteger e;

private BigInteger d;

private BigInteger n;

public RSA()

{

this.initParams();

}

public RSA(char blockSep)

{

this.blockSep = blockSep;

this.initParams();

}

private void initParams()

{

rnd = new Random();

int p = 0, q = 0;

generatePQ(out p, out q);

}

private void getPrimeNum(Random rnd, out int n1, out int n2)

{

int firstNumber;

int secondNumber;

do

{

firstNumber = rnd.Next(10000, 20000);

secondNumber = rnd.Next(10000, 20000);

}

while (!Utilities.MillerRabin(firstNumber, 10) || !Utilities.MillerRabin(secondNumber, 10));

n1 = firstNumber;

n2 = secondNumber;

}

private BigInteger NOD(BigInteger a, BigInteger b)

{

while (a != 0 && b != 0)

{

if (a > b)

a %= b;

else

b %= a;

}

return a == 0 ? b : a;

}

// 2. найти модуль

private BigInteger getN(int p, int q)

{

return p * q;

}

// 3. найти значение функции Эйлера fi

private BigInteger getFi(int p, int q)

{

return (p - 1) * (q - 1);

}

// 4. выбрать число е, взаимное простое с fi

private BigInteger getPrime(Random rnd, BigInteger fi)

{

BigInteger e = rnd.Next(1, Math.Abs((int)fi));

do

{

if (NOD(e, fi) == 1)

break;

else e++;

} while (true);

if (e >= fi)

{

e--;

do

{

if (NOD(e, fi) == 1)

break;

else e--;

} while (true);

}

return e;

}

// 5. найти d при помощи расширенного алгоритма Евклида

private BigInteger getD(BigInteger e, BigInteger fi)

{

BigInteger i = fi, v = 0, d = 1;

while (e > 0)

{

BigInteger t = i / e, x = e;

e = i % x;

i = x;

x = d;

d = v - t * x;

v = x;

}

v %= fi;

if (v < 0)

v = (v + fi) % fi;

return v;

}

private string encrypt(int symbol, BigInteger keyE, BigInteger keyN)

{

return BigInteger.ModPow(symbol, keyE, keyN).ToString();

}

private int decrypt(int symbol, BigInteger keyD, BigInteger keyN)

{

return (int)(BigInteger.ModPow(symbol, keyD, keyN));

}

private string textEncrypt(string text, BigInteger e, BigInteger n)

{

string eText = "";

foreach (var symbol in text)

eText += encrypt(symbol, e, n) + this.blockSep;

return eText;

}

private string textDecrypt(string text, BigInteger d, BigInteger n)

{

string[] arr = text.Split(this.blockSep);

string dText = "";

foreach (var symbol in arr)

if (symbol != string.Empty)

dText += Convert.ToChar(decrypt(int.Parse(symbol), d, n));

return dText;

}

public string getEncryptedText(string originalText)

{

return textEncrypt(originalText, this.e, this.n);

}

public string getEncryptedText(string originalText, int p, int q)

{

BigInteger fi = getFi(p, q);

this.n = getN(p, q);

this.e = getPrime(rnd, fi);

this.d = getD(e, fi);

Console.WriteLine("d = {0}, n = {1}", this.d.ToString(), this.n.ToString());

return textEncrypt(originalText, this.e, this.n);

}

public string getDecryptedText(string encryptedText)

{

return textDecrypt(encryptedText, this.d, this.n);

}

public string getDecryptedText(string encryptedText, BigInteger d, BigInteger n)

{

this.d = d;

this.n = n;

return textDecrypt(encryptedText, this.d, this.n);

}

public void generatePQ(out int p, out int q)

{

getPrimeNum(rnd, out q, out p);

BigInteger fi = getFi(p, q);


this.n = getN(p, q);

this.e = getPrime(rnd, fi);

this.d = getD(e, fi);

}

}

}

Листинг А2. Utilities.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Numerics;

using System.Text;

namespace RSAForm

{

public class Utilities

{

public static bool MillerRabin(int n, int k)

{

for (int i = 0; i < k; i++) // цикл по количеству раундов

{

// проверка элементарных случаев:

if (n % 2 == 0)

return false;

if (n == 2)

return true;

if (n <= 1)

return false;

// представление n - 1 как 2 ^ s * m

int s = 0;

int m = n - 1;

while (m % 2 == 0)

{

s++;

m = m / 2;

}

// выбор случ. целого числа a в отрезке [2, n − 2]

Random r = new Random();

int a = r.Next(n - 1) + 1;

// поиск mod = a ^ m % n

int temp = m;

long mod = 1;

for (int j = 0; j < temp; j++)

mod = (mod * a) % n;

// вычислить в цикле mod как mod ^ 2 % n

while (temp != n - 1 && mod != 1 && mod != n - 1)

{

mod = (mod * mod) % n;

temp *= 2;

}

// если mod = 1, то составное

// если mod != n - 1, то составное

if (mod != n - 1 && temp % 2 == 0)

return false;

}

return true; // вернуть "вероятно простое"

}

}

}

Листинг А3. Form1.cs

using System;

using System.Windows.Forms;

namespace RSAForm

{

public partial class Form1 : Form

{

RSA rsa;

public Form1()

{

InitializeComponent();

rsa = new RSA();

}

private void TextBox_p_KeyPress(object sender, KeyPressEventArgs e)

{

if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))

{

e.Handled = true;

}

}

private void ButtonEncrypt_Click(object sender, EventArgs e)

{

string plaintext = textBox_plaintext.Text;

int p, q;

if (!generatePQ.Checked)

{

if (!int.TryParse(textBox_p.Text, out p) || !Utilities.MillerRabin(p, 10))

{

MessageBox.Show("Не удалось считать простое число p!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);

return;

}

if (!int.TryParse(textBox_q.Text, out q) || !Utilities.MillerRabin(q, 10))

{

MessageBox.Show("Не удалось считать простое число q!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);

return;

}

textBox_ciphertext.Text = rsa.getEncryptedText(plaintext, p, q);

}

else

{

rsa.generatePQ(out p, out q);

textBox_p.Text = p.ToString();

textBox_q.Text = q.ToString();

textBox_ciphertext.Text = rsa.getEncryptedText(plaintext);

}

sameDecipherButton.Enabled = true;

}

private void ButtonDecipher_Click(object sender, EventArgs e)

{

string cipherText = textBox_ciphertext.Text;

int d, n;

if (!int.TryParse(textBox_d.Text, out d))

{

MessageBox.Show("Не удалось считать число d!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);

return;

}

if (!int.TryParse(textBox_n.Text, out n))

{

MessageBox.Show("Не удалось считать число n!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);

return;

}

textBox_plaintext.Text = rsa.getDecryptedText(cipherText, d, n);

}

private void SameDecipherButton_Click(object sender, EventArgs e)

{

string cipherText = textBox_ciphertext.Text;

textBox_plaintext.Text = rsa.getDecryptedText(cipherText);

sameDecipherButton.Enabled = false;

}

private void TextBox_ciphertext_TextChanged(object sender, EventArgs e)

{

sameDecipherButton.Enabled = false;

}

}

}

Листинг B1. Form1.cs

using System;

using System.Collections.Generic;

using System.Drawing;