МIНIСТЕРСТВО ОСВIТИ І НАУКИ, МОЛОДІ ТА СПОРТУ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
Звіт
про виконання графічно-розрахункової роботи
з курсу «Операційні системи»
на тему «Розроблення багатопоточної Windows Forms програми
для реалізації алгоритму шифрування RSA»
Варіант №10
Перевірив:
Павельчак А.Г.
Львів 2013
Мета роботи : розробити програму мовою C# для шифрування та розшифрування файлів з використанням асиметричних криптосистем з відкритими ключами на прикладі RSA. Алгоритми шифрування та розшифрування реалізувати з використанням багатопоточності Windows Forms.
Завдання
Мовою С# розробити окремий клас реалізації алгоритму з відкритим ключем RSA та побудувати Windows Forms програму (рис. 1) для генерування ключів RSA та шифрування/дешифру-вання файлів. Функціонування програми умовно розбити на дві частини: Система RSA – передбачає генерування закритого/відкри-того ключів, шифрування відкритим ключем вибраного в діалого-вому вікні файла, дешифруваня файла, згідно закритого ключа; Злом RSA – передбачає підбір (відновлення) закритого ключа згідно відкритого ключа простим методом перебору та дешиф-рування вказаного файла.
Усю функціональну роботу (генерування ключів, шифрування та дешифрування файлів) виконувати в окремих потоках. При виконанні роботи у вторинному потоці передбачати блокування кнопок виклику ( button1.Enabled = false; ) та розблокуван-ня їх після закінчення. По завершенню шифрування чи роз-шифрування файла виводити відповідне інформаційне вікно ( MessageBox.Show ("Шифрування завершено"); ).
Алгоритми
Алгоритм піднесення до степеню:
1.1. Метод справа-наліво двійкового потенціювання;
1.2. Метод зліва-направо двійкового потенціювання;
1.3. Рекурсивний метод двійкового потенціювання;
1.4. Метод вікна;
1.5. Метод змінного вікна.
Обч. найбільшого спільного дільника:
2.1. Алгоритм Евкліда;
2.2. Бінарний алгоритм Евкліда;
Обч. оберненого значення за модулем:
3.1. Розширений алгоритм Евкліда;
3.2. Розширений бінарний алгоритм Евкліда.
4. Тести визначення простоти числа:
4.1. Тест Рабіна-Мілера;
4.2. Тест Соловея-Штрасена;
4.3. Тест Лемана.
Таблиця 1. Завдання до розрахункової роботи
№
п/п
Завдання до RSA
Реалізація багатопоточності
10
Заяць Любомир
δ =10−20
Алг: 1.2; 2.2; 3.2; 4.2
Асинхронний виклик делегатів
Вигляд клієнтської частини програми
Програмний код:
Код форми програми:
using System;
using System.Windows.Forms;
namespace project_rozraha
{
public partial class Form1 : Form
{
ulong q = 1, p = 1, n = 1, E = 1,D1=1;
bool flag = false; // зміна для перевірки наявності згенерованих ключів
bool flag1 = false; // зміна для перевірки наявності зломаного ключа
ulong D = 1;
Button el;
string name_file = "";
rsa_protocol.keys key;
public Form1()
{
InitializeComponent();
}
private delegate void new_delegat();
private delegate string new_file_delegat();
private delegate bool deleg_shyfr();
private delegate void deleg_de_shyfr(ulong n ,ulong D);
// ================ Виклик делегатів =======
private bool shyfruvanja()
{
if (!flag) MessageBox.Show("Ключі не згенеровані");
else
{
IAsyncResult res= BeginInvoke(new new_delegat(druk), null);
while (!res.IsCompleted) ;
if (name_file != "" && name_file != "openFileDialog1" )
{
encryption.shyfr(name_file, n, E);
MessageBox.Show("Шифрування завершено");
}
}
BeginInvoke(new new_delegat(butt), null);
return true;
}
private void rozshyfruvania(ulong n, ulong D)
{
IAsyncResult result = BeginInvoke(new new_delegat(druk), null);
while (!result.IsCompleted) ;
if (name_file != "" && name_file != "openFileDialog1")
{
encryption.de_shyfr(name_file, n, D);
MessageBox.Show("Розшифрування завершенно");
}
BeginInvoke(new new_delegat(butt), null);
}
void butt()
{
el.Enabled = true;
}
void druk()
{
name_file = "";
openFileDialog1.ShowDialog();
name_file = openFileDialog1.FileName;
}
/*private void metod_de_shyfr()
{
el.BeginInvoke(new new_delegat(rozshyfruvania), null);
}
private void metod_shyfr()
{
// el.BeginInvoke(new new_delegat(shyfruvanja), null);
}*/
//================================================
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
MessageBox.Show("Автор програми студент групи СІ-31 Заєць Любомир");
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Close();
}
private void button2_Click(object sender, EventArgs e)
{
el = button2;
el.Enabled = false;
deleg_shyfr D = shyfruvanja;
IAsyncResult result = D.BeginInvoke(null, null);
}
private void button1_Click(object sender, EventArgs e)
{
flag = true;
q = rsa_protocol.generator();
textBox2.Text = Convert.ToString(q);
p = rsa_protocol.generator();
//p = rsa_protocol.generator();
textBox1.Text = Convert.ToString(p);
n = p * q;
textBox3.Text = Convert.ToString(n);
E = rsa_protocol.generetor_e(p, q);
textBox4.Text = Convert.ToString(E);
D = (ulong)rsa_protocol.Evklid_modyfi_bin(E, (p - 1) * (q - 1));
textBox5.Text = Convert.ToString(D);
// D1 = Convert.ToUInt64(D);
}
private void button4_Click(object sender, EventArgs e)
{
// new_delegat D = metod;
// D.BeginInvoke(null, null);
key = rsa_protocol.zlom(Convert.ToUInt64(textBox7.Text), Convert.ToUInt64(textBox6.Text));
// key = rsa_protocol.zlom(n, E);
textBox8.Text = Convert.ToString(key.p);
textBox9.Text = Convert.ToString(key.q);
textBox10.Text = Convert.ToString(key.D);
flag1 = true;
}
private void button3_Click(object sender, EventArgs e)
{
el = button3;
button3.Enabled = false;
deleg_de_shyfr B = rozshyfruvania;
//IAsyncResult result = B.BeginInvoke(1, D, null, null);
IAsyncResult result = B.BeginInvoke(key.n, D, null, null);
}
private void button5_Click(object sender, EventArgs e)
{
if (flag1 == true)
{
el = button5;
button5.Enabled = false;
deleg_de_shyfr A = rozshyfruvania;
IAsyncResult result = A.BeginInvoke(key.n, key.D, null, null);
}
else
MessageBox.Show("Секретний ключ не зломано розшифрування файлу не можливе");
}
private void mainToolStripMenuItem_Click(object sender, EventArgs e)
{
}
private void button6_Click(object sender, EventArgs e)
{
openFileDialog1.ShowDialog();
name_file = openFileDialog1.FileName;
}
}
}
Код алгоритмів шифрування:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using project_rozraha;
namespace project_rozraha
{
class encryption
{
public static Form1 TForm = new Form1();
public static void shyfr(string filename, ulong n, ulong E)
{
byte p;
uint m;
ulong m1, c;
//TForm
BinaryReader bin_read = new BinaryReader(File.Open(filename, FileMode.Open));
BinaryWriter bin_write = new BinaryWriter(File.Open(filename+".rsa", FileMode.Create));
try
{
do
{
p = bin_read.ReadByte();
m1 = (ulong)p;
//c = rsa_protocol.poteciuvania(m1, E, n);
c = rsa_protocol.stepMod(m1, E, n);
m = (UInt32)c;
bin_write.Write(m);
}
while (1 > 0);
}
catch { }
bin_read.Close();
bin_write.Close();
}
public static void de_shyfr(string filename, ulong n, ulong D)
{
byte p;
uint c1;
ulong m, c;
BinaryReader bin_read = new BinaryReader(File.Open(filename, FileMode.Open));
BinaryWriter bin_write = new BinaryWriter(File.Open(filename.Replace(".rsa",""), FileMode.Create));
try
{
do
{
c1 = bin_read.ReadUInt32();
c = Convert.ToUInt64(c1);
// m = rsa_protocol.poteciuvania(c,D, n);
m = rsa_protocol.stepMod(c, D, n);
p = Convert.ToByte(m);
bin_write.Write(p);
}
while (1 > 0);
}
catch { }
bin_read.Close();
bin_write.Close();
}
}
}
Код числових алгоритмів RSA:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace project_rozraha
{
class rsa_protocol
{
public static Random rand = new Random();
public struct keys
{
public ulong p;
public ulong q;
public ulong D;
public ulong n;
public ulong E;
}
public static ulong Evklid(ulong a, ulong b)
{
ulong g = 1;
while (a % 2 == 0 && b % 2 == 0)
{ a /= 2; b /= 2; g *= 2; }
while (a != 0)
{
while (a % 2 == 0) a /= 2;
while (b % 2 == 0) b /= 2;
if (a >= b) a = Convert.ToUInt64( (a - b) / 2);
else
b = (b - a) / 2;
}
return g * b;
}
public static ulong poteciuvania(ulong a, ulong x, ulong n)
{
ulong m = 1;
while (x > 0)
{
if (x % 2 != 0) m = (m * a) % n;
x = x >> 1;
a = (a * a) % n;
}
return m;
}
public static ulong alg_1_2(ulong a, ulong x, ulong n)
{
ulong worker = x;
int n_x = 1;
while (worker > 1) { worker = worker >> 1; n_x++; }
ulong mask = 1;
mask = mask << (n_x - 1);
ulong m = 1;
while (mask > 0)
{
m = (m * m) % n;
if (x % mask != 0) m = (m * a) % n;
mask = mask >> 1;
}
return m;
}
public static ulong stepMod(ulong a, ulong x, ulong n)
{
ulong temp;
if (x == 1) return a % n;
if ((x&1)!=0)
{
temp = stepMod(a, x >> 1, n);
temp = (temp * temp) % n;
return (temp * a) % n;
}
else
{
temp = stepMod(a, x >> 1, n);
return (temp * temp) % n;
}
}
//public static long Evklid_modyfi(ulong a, ulong n)
//{
// long n1, c, k, nsd, c1, c2, k1, k2, q, r;
// n1 = Convert.ToInt64(n);
// c2 = 1; c1 = 0; k2 = 0; k1 = 1;
// while (n != 0)
// {
// q =(long)a /(long) n; r = (long)a - q * (long)n; c = c2 - q * c1; k = k2 - q * k1;
// a = n; n = (ulong)r; c2 = c1; c1 = c; k2 = k1; k1 = k;
// }
// nsd = (long)a; c = c2; k = k2;
// if (c < 0) c += n1;
// return c;
//}
public static long Evklid_modyfi_bin(ulong A1, ulong N)
{
long a = Convert.ToInt64(A1);
long n = Convert.ToInt64(N);
long u, v, A, B, C, D, g, c, k, n1, nsd;
g = 1;
n1 = n;
while (a % 2 == 0 && n % 2 == 0)
{ a = a / 2; n = n / 2; g = g * 2; }
u = a; v = n; A = 1; B = 0; C = 0; D = 1;
do
{
while (u % 2 == 0)
{
u = u / 2;
if (A % 2 == 0 && B % 2 == 0) { A = A / 2; B = B / 2; }
else { A = (A + n) / 2; B = (B - a) / 2; }
}
while (v % 2 == 0)
{
v = v / 2;
if (C % 2 == 0 && D % 2 == 0) { C = C / 2; D = D / 2; }
else { C = (C + n) / 2; D = (D - a) / 2; }
}
if (u >= v) { u = u - v; A = A - C; B = B - D; }
else { v = v - u; C = C - A; D = D - B; }
}
while (u != 0);
nsd = g * v; c = C; k = D;
if (c < 0) c += n1;
return c;
}
public static bool Solovej_Strasen(ulong p, int t)
{
// Random rand = new Random();
int J, s, m;
ulong a, b, c, a1, p1;
for (int i = 0; i < t; i++)
{
a = Convert.ToUInt64(rsa_protocol.rand.Next(2, Convert.ToInt32(p - 1)));
if (Evklid(Convert.ToUInt64(a), p) != 1) return true;
c = poteciuvania(Convert.ToUInt64(a), (p - 1) / 2, p);
//c = alg_1_2(Convert.ToUInt64(a), (p - 1) / 2, p);
J = 1; p1 = p;
do
{
if (a == 0) { J = 0; break; }
if (a == 1) { break; }
a1 = a; m = 0;
while (a1 % 2 == 0) { a1 = a1 / 2; m++; }
if (m % 2 == 0) s = 1;
else
{
if (p1 % 8 == 1 || p1 % 8 == 7) s = 1;
else s = -1;
}
if (a1 == 1) { J = J * s; break; }
if (p1 % 4 == 3 && a1 % 4 == 3) s = -s;
a = p1 % a1; p1 = a1; J *= s;
}
while (1>0);
if (J < 0) b = p +(ulong) J;
else b =(ulong) J;
if (b != c) { return true; }
}
return false;
}
//public static bool Leman(ulong p, int t)
//{
// Random rand = new Random();
// ulong c;
// int a = 0;
// for(int i=0;i<t;i++)
// {
// a = rand.Next(2, Convert.ToInt32(p - 1));
// if (Evklid(Convert.ToUInt64(a), p) != 1) return true;
// c = poteciuvania(Convert.ToUInt64(a), (p - 1) / 2, p);
// //c = alg_1_2(Convert.ToUInt64(a), (p - 1) / 2, p);
// if (c != 1 && c != p - 1) return true;
// }
// return false;
//}
public static ulong generator()
{
// Random auto_rand = new Random();
//Random _rand_temp = new Random();
ulong a=0,mask;
int t=200;
bool flag = true;
do
{
flag = false;
a = Convert.ToUInt64(rsa_protocol.rand.Next(10000, 99999));
// a = 65534;
// mask = 1; a = a | 1; a = a | (mask << 15);
for(int i=3;i<2000;i+=2)
if (a % Convert.ToUInt64(i) == 0) { flag = true; break; }
//if (!flag) flag = Leman(a, 32000);
if (!flag) flag = Solovej_Strasen(a, 32000);
}
while (flag);
return a;
}
public static ulong generetor_e(ulong p, ulong q)
{
// Random _rand = new Random();
ulong E=0;
do
{
if (((p - 1) * (q - 1) >> 1) < int.MaxValue)
E = Convert.ToUInt64(rsa_protocol.rand.Next(3, Convert.ToInt32((p - 1) * (q - 1) >> 1)));
else { E = Convert.ToUInt64(rsa_protocol.rand.Next(3, int.MaxValue)); }
}
while (Evklid(E, (p - 1) * (q - 1)) != 1);
return E;
}
public static keys zlom(ulong n, ulong E)
{
ulong i=3;
while (i <= n)
{
if (n % i == 0) break;
i += 2;
}
keys key;
key.E = E;
key.n = n;
key.p = i;
key.q = n / key.p;
key.D = (ulong) Evklid_modyfi_bin(E, (key.p - 1) * (key.q - 1));
return key;
}
}
}
Висновок
В даній розрахунковій роботі я розробив програму мовою C# для шифрування та розшифрування файлів з використанням асиметричних криптосистем з відкритими ключами на прикладі RSA. Алгоритми шифрування та розшифрування реалізував з використанням багатопоточності Windows Forms.