Міністерство освіти і науки України
Національний університет ”Львівська політехніка”
КУРСОВА РОБОТА
з курсу
“МЕТОДИ ТА ЗАСОБИ КРИПТОЛОГІЧНИХ ПЕРЕТВОРЕНЬ”
Тема „Симетричні та асиметричні методи зашифрування інформації ”
Львів-2009
ЗМІСТ
Завдання 3
Опис систем шифрування
Афінний шифр зсуву першого порядку 4
RSA 4
Завдання 1 10
Ідентифікатори 10
Текст програми 11
Результат 13
Завдання 2
Завдання 2а) 14
Завдання 2б)
Ідентифікатори 14
Текст програми 16
Результат 24
Висновок 26
Використана література 27
ЗАВДАННЯ:
ОПИС СИСТЕМ ШИФРУВАННЯ:
Афінний шифр зсуву першого порядку
Ключ: 0 < n < s
Шифрування: у повідомлення кожна буква заміняється буквою E(x)=(x+s) mod n.
Дешифрування: у криптотексті кожна буква x’ заміняється D(x’)=(x’+s’) mod n, де s’= n – s .
Шифр зсуву з ключем s = 3 названо шифром Цезаря.
Шифр Цезаря (100-44 р. до н. є.).
Його названо за іменем римського імператора Гая Юлія Цезаря, який доручав Цицерону складати шифровані повідомлення для керування військами. Літери абетки тут ототожнені з цифрами. В системі Цезаря використано 26 символів (26
літер ла-тинської абетки), які перенумеровані числами від 0 до 25 . Шифр ґрунтується на підстановці:
00 (а) -> 03 (d); 01 (b) -> 04 (e); 02 (с) -> 05 (f);...; 25 (z) -> 02 (с).
Це означає, що в шифрограмі кожну літеру явного тексту замінюють на літеру, розташовану в абетці на три позиції далі. Висловлюючись сучасною мовою, римляни застосовували операцію додавання до номера літери числа З за модулем 26: С = Р + 3(mod 26), де С - номер літери в криптограмі, а Р - номер відповідної літери в явному тексті. Наприклад, латинському тексту Veni, vidi, vici (прийшов, побачив, переміг - крилата фраза Цезаря), коли з нього викинути коми й пропуски між словами, відповідає криптограма yhqlylglylfl.
Шифр Цезаря стосовно української абетки означає, що літеру а заміню-ють на літеру г, літеру б - на літеру ґ, літеру в - на літеру д і т.д. Останні букви абетки ь, ю, я зміщуються циклічно, тобто переходять у а, б, в, відповідно. Наприклад, слову імперія відповідає криптограма кптзукв.
RSA
Перший алгоритм кодування з відкритим ключем (Public Key Encryption, далі PKE) було запропоновано Вітфілдом Діффі та Мартіном Хелманом у Стендфордському університеті. Вони, а також незалежно від них Ральф Меркл, розробили основні його поняття у 1976 році. Перевага PKE полягає у відсутності потреби секретної передачи ключа.
PKE базується на нерозв’язності проблеми розкладу натурального числа на прості множники.
RSA схему шифрування було запропоновано у 1978 році та названо іменами трьох його винахідників: Роном Рівестом (Ron Rivest), Аді Шаміром (Adi Shamir) та Леонардом Адлеманом (Leonard Adleman). RSA належить до класу алгоритмів кодування з відкритим ключем.
У 80-х роках криптосистема переважно використовувалася для забезпечення секретності та достовірності цифрових даних. У сучасному світі RSA використовується в web – серверах та браузерах для зберігання таємності даних що передаються по мережі, .
Схема RSA базується на обчисленні виразів зі степенями. Відкритий текст шифрується блоками, довжина кожного із яких менша за деяке число n.
Алгоритм генерації ключа
A повинен згенерувати відкритий та секретний ключі:
1. Згенерувати два великих простих числа p та q приблизно однакової довжини;
2. Обчислити n = p * q, fi = (p – 1) * (q – 1);
3. Вибрати натуральне e, 1 < e < fi, взаємно просте з fi;
4. Використовуючи розширений алгоритм Евкліда, розв’язати рівняння
d * e 1 (mod fi).
Відкритий ключ: (n, e). Секретний ключ: d.
Схема шифрування RSA
B шифрує повідомлення m та надсилає A.
1. Шифрування. В робить наступні дії:
а) отримати відкритий ключ (n, e) від А;
б) представити повідомлення у вигляді натурального числа m з проміжку [1..n];
в) обчислити c = me mod n;
г) надіслати шифротекст c до А.
2. Дешифрування. Для отримання повідомлення m із шифротксту c А робить наступні дії:
а) використовуючи секретний ключ d, обчислити m = cd mod n.
Теорема. Шифр c декодується правильно.
Оскільки p та q – прості числа, то (p * q) = (n) = (p - 1) * (q - 1), де – функція Ейлера. З умови вибору ключа d маємо: d * e mod (n) = 1, або d * e = (n) * k + 1 для деякого натурального k.
cd mod n = (me)d mod n = m (e * d) mod n = m ^ ( (n) * k + 1) mod n = (m (n) mod n) k * m = 1 k * m = m, оскільки за теоремою Ейлера m (n) mod n = 1.
Означення. RSA системою називають функцію RSAn,e(x) = xe mod n та обернену їй RSA-1n,e(y) = yd mod n, де e – кодуюча, а d – декодуюча експонента, x, y Zn*.
Приклад
1. Оберемо два простих числа: p = 17, q = 19;
2. Обчислимо n = 17 * 19 = 323, fi = (p - 1) * (q - 1) = 16 * 18 = 288;
3. Оберемо e = 7 (НСД(e, fi) = 1) та розв’яжемо рівняння 7 * d 1 (mod 288), звідки d = 247.
Побудовано RSA систему: p = 17, q = 19, n = 323, e = 7, d = 247.
Відкритий ключ: n = 323, e = 7, секретний ключ: d = 247.
1. m = 4. Кодування: 47 mod 323 = 234. Декодування: 234247 mod 323 = 4.
2. m = 123. Кодування: 1237 mod 323 = 251. Декодування: 251247 mod 323 = 123.
Циклічна атака
За відомим шифром c (c = me mod n) злодій, маючи відкритий ключ e та n, бажає знайти повідомлення m. Він починає будувати послідовність чисел
c, ce, , , …
Оскільки обчислення відбуваються в групі Zn*, то елемпнти послідовності знаходяться в межах від 0 до n - 1. Отже існує таке натуральне k, що с = . Враховуючи що c = me mod n, маємо: me = або m = .
Таким чином для знаходження повідомлення m за його шифром c необхідно побудувати послідовність c, ce, , , …, , = c, і взяти її передостаннє число.
Приклад
Розв’язати рівняння: m7 mod 323 = 251.
e = 7, n = 323, c = 251.
k
0
251
1
310
2
47
3
4
4
234
5
123
6
251
З таблиці маємо: c = = 251. Оскільки me = , то m = = 123.
Атака методом осліплення
Припустимо, А має секретний ключ RSA системи, а Z – злодій, який перехопив шифр c і хоче декодувати його. При цьому А відмовляє видати Z вихідний текст m. Тоді Z обирає деяке значення b Zn*, обчислює c’ = be * c і просить А дешифрувати його. А погоджується дешифрувати c’ своїм секретним ключем d, оскільки зміст повідомлення c’ йому ні про що не говорить і виглядає невинним. Отримавши m’ = c’d mod n, злодій Z обчислює m = m’ / b і отримує шукане m. Шифром m дійсно є c, оскільки me = m’e / be = c’de / be = c’ / be = c.
Така атака можлива, оскільки А не знає повної інформації про шифр c’, який дає йому злодій Z.
Приклад. Нехай А має RSA систему: p =17, q = 19, n = 323, e = 7, d = 247.
Злодій Z перехопив шифр c = 234 і хоче знайти таке m, що m7 = 234 mod 323.
1. Z обирає b = 10 Z323*, обчислює c’ = 107 * 234 mod 323 = 14 і просить А дешифрувати його.
A обчислює m’ = 14247 mod 323 = 40 і передає його Z.
3. Z знаходить шукане повідомлення обчислюючи
m = 40 / 10 = 40 * 10-1 = 40 * 97 = 4 mod 323.
Таким чином 47 = 234 mod 323.
Прискорення дешифрування
За допомогою китайської теореми про лишки можна прискорити процес дешифрування, знаючи секретні прості числа p та q.
Алгоритм
Дешифрування. А має декодуючу експоненту d, а також p та q (n = p * q). А отримує від В шифр с та повинен виконати операцію cd (mod n).
1. Обчислити dp = d mod (p - 1), dq = d mod (q - 1)
2. Обчислити mp = mod p, mq = mod q.
3. Розв’язати систему лінійних порівнянь
Розв’язком системи буде декодоване повідомлення: m = cd (mod n).
Приклад
Нехай RSA система має вигляд: p = 17, q = 19, n = 323, e = 7, d = 247.
Для розв’язку рівняння m7 mod 323 = 251 (c = 251) обчислимо 251247 mod 323:
1. dp = 247 mod 16 = 7, dq = 247 mod 18 = 13;
2., mp = 2517 mod 17 = 4, mq = 25113 mod 19 = 9;
3. Розв’яжемо систему лінійних порівнянь
Розв’язуючи її методом Гауса, отримаємо m = 123.
Отже 1237 mod 323 = 251.
Мала декодуюча експонента
Приклад. Виберемо повідомлення m = 13 та зашифруємо його трьома різними RSA системами.
1. p = 5, q = 17, n = 85, e = 3, d = 57,
m3 mod 85 = 72;
2. p = 11, q = 23, n = 253, e = 3, d = 169,
m3 mod 253 = 173;
3. p = 17, q = 23, n = 391, e = 3, d = 261,
m3 mod 391 = 242;
Для знаходження повідомлення m за відкритими ключами (ni, ei ) та перехопленими шифрами ci складемо систему порівнянь
Одним із її розв’язків буде x = 2197 = 133. Тобто шуканим повідомленням буде m = 13.
Неприховані повідомлення
Означення. Повідомлення m називається неприхованим, якщо його шифр дорівнює самому повідомленню, тобто me = m (mod n).
Наприклад, повідомлення m = 0 та m = 1 завжди є неприхованими для довільних значень e та m.
Твердження. Кількість неприхованих повідомлень в RSA системі дорівнює
(1 + НСД(e - 1, p - 1)) * (1 + НСД(e - 1, q - 1))
Оскільки значення e - 1, p - 1 та q - 1 – парні, то НСД(e - 1, p - 1) 2, НСД(e - 1, q - 1) 2, а отже кількість неприхованих повідомлень завжди не менша за 9.
Завдання 1
РОЗРОБЛЕННЯ АЛГОРИТМУ ЗАШИФРУВАННЯ АФІННИМ ШИФРОМ.
Тип шифру – шифр зсуву першого порядку.
Об’єм алфавіту
Ідентифікатори
source – файл з якого проводиться зчитування даних, що необхідно зашифрувати;
zasch – файл в який здійснюється запис зашифрованих даних;
ALFAVIT – масив символів даного алфавіту;
N – об’єм алфавіту;
zsuv – величина зсуву;
z – задана величина блоку в бітах для читання;
zw – задана величина блоку в бітах для запису;
f – довжина блоку зчитуваних даних в бітах;
fw – довжина блоку запису даних в бітах;
Y – залишок при виділенні блоку заданої довжини при зчитуванні даних;
YW – залишок при виділенні блоку заданої довжини при записі даних;
s – прапорець необхідності зчитування даних;
sw – прапорець необхідності дописування даних до блоку, який необхідно буде записати у файл;
M – блок відкритого тексту заданої довжини;
MWRITE – блок зашифрованого тексту заданої довжини;
C – байт зашифрованого тексту;x – зчитане з файлу f-бітове число;
l – кількість біт,що необхідно дочитати з файлу;
lw – кількість біт,що необхідно дописати до байту;
xx – старші біти зчитаного блоку;
xxw – старші біти зашифрованого блоку;
Vubir – визначає якому байту(старшому чи молодшому) присвоїти черговий зашифрований байт;
kk – визначає наявність старшого і молодшого байту, надає дозвіл на запис у файл двох зашифрованих бітів;
C_LOW, C_HIGH – молодший байт і старший байт;
position – порядок зчитаного блоку а алфавіті;
position_new – порядок зашифрованого блоку алфавіті.
Текст програми
#include<stdio.h>
#include<stdlib.h>
#define N 1024
unsigned short ALFAVIT[N];
int main(void)
{
unsigned short z=10,zw=8;
unsigned short f=16,fw=10;
unsigned short Y=0,YW=0;
int l=z,lw=zw;
unsigned short s=1,sw=1;
unsigned short M,MWRITE,C;
unsigned short x,xx,xxw;
int Vubir=0,kk=0;
unsigned short xxx;
unsigned char C_LOW,C_HIGH;
int zsuv,i,position_new;
unsigned short position;
FILE *source,*zasch;
for(i=0;i<N;i++)
ALFAVIT[i]=i;
printf("Vvedit velu4inu zsuvu\n");
scanf("%i",&zsuv);
source=fopen("c:\\bin.txt","rb");
zasch = fopen("C:\\zasch.txt","wb");
while(!feof(source))
{
if(s==0)
{
M=Y>>(f-z);
Y=Y<<z;
if(l>0)
{
s=1;
}
else
{
l=z+l;
}
}
else
{
Y=Y>>(f-z);
fread(&x,2,1,source);
xx=x>>(f-l);
M=((Y|xx));
Y=x<<l;
l=(z-(f-l));
if(l<=0)
{
s=0;
l=z+l;
}
}
/*****************************************************************/
for(i=0;i<N;i++)
if(M==ALFAVIT[i])
{
position=i;
break;
}
position_new=(position+zsuv)%N;
if(position_new<0)
position_new=(N+position_new);
MWRITE=ALFAVIT[position_new];
printf("M=%u\n",M);
printf("MWRITE=%u\n",MWRITE);
/******************************************************************/
label:
if(sw==0)
{
if(Vubir%2==1)
{
C_HIGH=C;
kk+=1;
}
else
{
kk+=1;
C_LOW=C;
}
if(kk==2)
{
printf("WRITE TWO BYTES\n");
printf("C_LOW=%u\n",C_LOW);
printf("C_HIGH=%u\n\n",C_HIGH);
fwrite(&C_LOW,1,1,zasch);
fwrite(&C_HIGH,1,1,zasch);
kk=0;
}
C=(unsigned char)(YW>>(fw-zw));
YW=YW<<zw;
Vubir+=1;
if(lw>0)
{
sw=1;
}
else
{
lw=zw+lw;
}
}
else
{
YW=YW>>(fw-zw);
xxw=MWRITE>>(fw-lw);
C=(unsigned char)(YW|xxw);
Vubir+=1;
YW=((MWRITE<<lw));
lw=(zw-(fw-lw));
if(lw<=0)
{
sw=0;
lw=zw+lw;
goto label;
}
}
if(Vubir%2==1)
{
C_HIGH=C;
kk+=1;
}
else
{
kk+=1;
C_LOW=C;
}
if(kk==2)
{
printf("WRITE TWO BYTES\n");
printf("C_LOW=%u\n",C_LOW);
printf("C_HIGH=%u\n\n",C_HIGH);
fwrite(&C_LOW,1,1,zasch);
fwrite(&C_HIGH,1,1,zasch);
kk=0;
}
}
fclose(source);
fclose(zasch);
system("PAUSE");
return 0;
}
Результат
Вміст файлу c:\\bin.txt
RSA схему шифрування було запропоновано у 1978 році та названо іменами трьох його винахідників: Роном Рівестом (Ron Rivest), Аді Шаміром (Adi Shamir) та Леонардом Адлеманом (Leonard Adleman). RSA належить до класу алгоритмів кодування з відкритим ключем.
У 80-х роках криптосистема переважно використовувалася для забезпечення секретності та достовірності цифрових даних. У сучасному світі RSA використовується в web – серверах та браузерах для зберігання таємності даних що передаються по мережі, .
Схема RSA базується на обчисленні виразів зі степенями. Відкритий текст шифрується блоками, довжина кожного із яких менша за деяке число n.
Вміст файлу С:\\zasch.txt
ЏJµяйТґ*Р”6аhАлї°+Кs^Шf»жэ·Мd,зbЅжїї+Л”1Ґ/р-Лjсf°К°%їT+ж”‚дВЅЙ\^йdМжТр&ЛW,VёдЅЕсБa&в&І2э ,Кb*DѓЪВБ0Л`^Е>eэ!§SЩ°kќыќґсэOд'АеЙяeШ§З7XJ8°”0Ш”љЭЛЅНX,д”џЬИµ*Ѕa+д”чCB>¬>жўµ3cB<џKќlЕ"9эЅИY$аfМБѕ^З_йgрШИі,Н\0д'ІЗѕ"РVеaПДрђX(и\ВаЙр'Иr4ЭcюкЩэЇm$iриЛ№Т”(и\їкЛБ&Оf"дTрзВА#їT#еbрЪЕє,Н\/кbІлї°)Ѕe=[»чэ·ѕY%зYЗЭКЅ=эd#вdµкКѕ/П']йTрЬЛБ0ЛVсзaѕиПѓ^У\2иbІаТр!Ѕa%нЎяЛэБ1ФT/еaјлэБ ђfсЕ"9эІ&Зb.аeВеїГшПp/ч”±T5 э ^иYАЪВПТ”0Ш”°иЅГ%Вdн”ігЬр$ѕY.«W°дКП^ПTшгaѕиПѓ^БT*аiрсЛр,Вd#ЬTОкЩБ=эb,`µзВµс ”l~ нВ»эЕ‘8”°ЧДГшПp/ч—јШэѕФ\/гYЅеђрЕdЯ'ІДѓ^Оf#зYЅцЙёlэ5сЫ^АаПё'эe#вeВХё2НgшйsБчэ±)Л^д\ьБѕ Г\+Ш”№жГЅ,Аb]Є[рчЗё3эc#еl°Д°^БY<вYрпЕА)Л”«%ЂЩ
Завдання 2
а)
Нехай
НСД(72,23)=1
ФОН -----> 24 18 17
19 86 75
б) Ідентифікатори
long long* SimpleNumb(long long begin,long long end,long long *k_t) – функція повертає масив простих чисел на проміжку від begin до end, k_t – кількість простих чисел на даному проміжку;
long long ReverseEvklid(long long modul, long long x) – функція повертає обернений елемент до x в кільці modul;
long* Dec_to_Bin2(long x, int *k) – функція повертає масив в якому записані біти числа x, а також вказує на адресу змінної за якою зберігається кількість бітів числа x;
long long Binary(long long x, long long y, long long m) – функція повертає значення , яке обчислюється за допомогою бінарного алгоритму,aj_modm – масив в якому зберігаються результати квадратів чергових лишків;
getrandom(min,max) – макрос що повертає випадкове число на проміжку від min до max;
N_ALF – об’єм алфавіту;
ALFAVIT – алфавіт;
p_key,q_key,n_key,e_key,d_key – ключі системи;
e_begin, e_end – початок і кінець поміжку в якому формується e_key;
Ojler_Function – функція Ойлера;
TAK_NI – дає можливість ввести свої ключі для зашифрування;
ll – використовується для ітерацій;
xxx – зберігає масив з простими числами;
dov – зберігає кількість елементів в масиві з простими числами;
source – файл з якого проводиться зчитування даних, що необхідно зашифрувати;
zasch – файл в який здійснюється запис зашифрованих даних;
z – задана величина блоку в бітах для читання;
zw – задана величина блоку в бітах для запису;
f – довжина блоку зчитуваних даних в бітах;
fw – довжина блоку запису даних в бітах;
Y – залишок при виділенні блоку заданої довжини при зчитуванні даних;
YW – залишок при виділенні блоку заданої довжини при записі даних;
s – прапорець необхідності зчитування даних;
sw – прапорець необхідності дописування даних до блоку, який необхідно буде записати у файл;
M – блок відкритого тексту заданої довжини;
MWRITE– блок зашифрованого тексту заданої довжини;
C – байт зашифрованого тексту;x – зчитане з файлу f-бітове число;
l – кількість біт,що необхідно дочитати з файлу;
lw – кількість біт,що необхідно дописати до байту;
xx – старші біти зчитаного блоку;
xxw – старші біти зашифрованого блоку;
Vubir – визначає якому байту(старшому чи молодшому) присвоїти черговий зашифрований байт;
kk – визначає наявність старшого і молодшого байту, надає дозвіл на запис у файл двох зашифрованих бітів;
C_LOW, C_HIGH – молодший байт і старший байт;
position – порядок зчитаного блоку а алфавіті;
Текст програми
/******************************************************************/
/******************* RSA *******************/
/******************* Golinko J. *******************/
/******************* 2009 *******************/
/******************************************************************/
#include<stdio.h>
#include<time.h>
#include<math.h>
#include<windows.h>
#include<stdlib.h>
#define getrandom(min,max) ((rand()%(int)(((max+1)-min)+min)))
#define NBIT 10
#define N_ALF 1024
/*----------------------------------------------------------------*/
/* Init Simple Numbers */
/*----------------------------------------------------------------*/
long long* SimpleNumb(long long begin, long long end, long long *k_t)
{
long long *Numb;
long long a,ost;
long long x1,i;
long long k,j=0;
for(a=begin;a<end;a+=2)
{
x1=(long long)(pow(a,0.5)+1);
i=3; k=0;
while(i<x1)
{
ost=a%i;
if(ost==0)
{
k=1;
break;
}
i+=2;
}
if(k==0)
{
j++;
}
}
*k_t=j;
Numb = (long long*)malloc(*k_t*sizeof(long long));
j=0;
for(a=begin;a<end;a+=2)
{
x1=(long long)(pow(a,0.5)+1);
i=3; k=0;
while(i<x1)
{
ost=a%i;
if(ost==0)
{
k=1;
break;
}
i+=2;
}
if(k==0)
{
Numb[j]=a;
j++;
}
}
return Numb;
}
/*================================================================*/
/*----------------------------------------------------------------*/
/* Reverse algorithm Evklid */
/*----------------------------------------------------------------*/
long long ReverseEvklid(long long modul, long long x)
{
long long u_i_1=1,v_i=1,u_i=0,v_i_1=0;
long long u,v,q;
long long a,b,r;
a=modul;
b=x;
while(1)
{
q=a/b;
r=a%b;
a=b;
b=r;
if(b==0) break;
u=u_i_1-q*u_i;
v=v_i_1-q*v_i;
u_i_1=u_i;
v_i_1=v_i;
u_i=u;
v_i=v;
}
if(v<0)
v=modul-v;
return v;
}
/*================================================================*/
long* Dec_to_Bin2(long x, int *k)
{
long ch_z=x,ch_ost;
long *Bin;
int i=0,N=0;
while(1)
{
ch_z=ch_z/2;
if(ch_z==0)
break;
N++;
}
ch_z=x;
*k=N+1;
Bin=(long *)malloc((N+1)*sizeof(long));
for(i=0;i<*k;i++)
Bin[i]=0;
i=0;
while(i<N+1)
{
ch_ost=ch_z%2;
ch_z=ch_z/2;
Bin[i]=ch_ost;
i++;
}
return Bin;
}
long long Binary(long long x, long long y, long long m)
{
long long *p;
int k,i,n;
long long step;
int j[40]={0};
long long aj_modm[40]={0};
long long dob=1;
p=Dec_to_Bin2(y,&k);
for(i=0;i<k;i++)
{
step=(long long)pow(2,i) ;
if(i==0)
aj_modm[i]=((long long)pow(x,step))%m;
else
aj_modm[i]=(aj_modm[i-1]*aj_modm[i-1])%m;
}
for(i=0;i<k;i++)
{
if(y%2)
{
dob*=aj_modm[i];
dob=dob%m;
}
y=y/2;
}
return dob ;
}
unsigned short ALFAVIT[N_ALF];
int main()
{
int x1;
long long *xxx;
long long dov,ll;
long long p_key,q_key,n_key,e_key,d_key;
int i;
int e_begin, e_end;
long long Ojler_Function;
int TAK_NI;
/*FOR READ AND WRITE FILE*/
unsigned short z=10,zw=8;
unsigned short f=16,fw=10;
unsigned short Y=0,YW=0;
int l=z,lw=zw;
unsigned short s=1,sw=1;
unsigned short M,MWRITE,C;
unsigned short x,xx,xxw;
int Vubir=0,kk=0;
unsigned char C_LOW,C_HIGH;
unsigned short position;
int position_new;
FILE *source, *zasch;
/*************************/
for(i=0;i<N_ALF;i++)
ALFAVIT[i]=i;
label_n_new:
/*------------ Generate casual key p ---------*/
xxx=SimpleNumb((long long)pow(2,NBIT/2)-1,(long long)pow(2,NBIT/2)+20,&dov);
srand((unsigned)time(NULL));
x1=getrandom(0,dov-1);
printf("Amount of the keys p ----> %d\n",dov-1);
printf("Number of the casual key p ----> %i\n",x1);
printf("The keys p are possible\n");
for(ll=0;ll<dov;ll++)
{
printf("%i ->",xxx[ll]);
printf(" %i \n",ll);
}
printf("Generate key p is -->");
printf(" p=%i\n",xxx[x1]);
p_key=xxx[x1];
/*================================================================*/
sleep(1500);
printf("\n");
/*-------- Generate casual key q ---------*/
xxx=SimpleNumb((long long)pow(2,NBIT/2)-1,(long long)pow(2,NBIT/2)+20,&dov);
srand((unsigned)time(NULL));
x1=getrandom(0,dov-1);
printf("Amount of the keys q ----> %d\n",dov-1);
printf("Number of the casual key q ----> %i\n",x1);
printf("The keys q are possible\n");
for(ll=0;ll<dov;ll++)
{
printf("%i ->",xxx[ll]);
printf(" %i \n",ll);
}
printf("Generate key q is -->");
printf(" q=%i\n",xxx[x1]);
q_key=xxx[x1];
/*================================================================*/
printf("\n");
/*--------- Generate casual key n ---------*/
n_key=p_key*q_key;
printf("n=p*q=%i*",p_key);
printf("%i=",q_key);
printf("%i\n",n_key);
/*================================================================*/
printf("\n");
/*--------- Ojler Function ----------*/
Ojler_Function=(p_key-1)*(q_key-1);
printf("Ojler Function --> %i",Ojler_Function);
/*================================================================*/
sleep(1500);
printf("\n");
/*-------- Generate casual key e --------*/
label:
printf("Enter a range key e [3,%u]\n", Ojler_Function-1);
printf("e_begin=");
scanf("%i",&e_begin);
if((e_begin<3)||(e_begin>Ojler_Function-1))
{
printf("\a\a\a\n");
printf("Going is beyond the settled range \n");
goto label;
}
printf("e_end=");
scanf("%i",&e_end);
if((e_end<e_begin)||(e_begin>Ojler_Function-1))
{
printf("\a\a\a\n");
printf("Going is beyond the settled range. It must be e_end > e_begin\n");
goto label;
}
xxx=SimpleNumb((long long)e_begin,(long long)e_end,&dov);
srand((unsigned)time(NULL));
x1=getrandom(0,dov-1);
printf("Amount of the keys e ----> %d\n",dov-1);
printf("Number of the casual key e ----> %i\n",x1);
printf("The keys e are possible \n");
for(ll=0;ll<dov;ll++)
{
printf("%i ->",xxx[ll]);
printf(" %i \n",ll);
}
printf("Generate key e is -->");
printf(" e=%i\n",xxx[x1]);
e_key=xxx[x1];
if(Ojler_Function%e_key==0)
goto label;
/*================================================================*/
/*-------- Generate casual key d ---------*/
d_key=ReverseEvklid(Ojler_Function,e_key);
printf("Generate key d is --> %u\n",d_key);
printf(" n=%u\n",n_key);
if(d_key>Ojler_Function)
{
printf("\a\a\nd > Ojler Function\nTo begin generation of the new keys?\n");
system("PAUSE");
goto label_n_new;
}
/*================================================================*/
printf("\n\n");
printf("GENERATE RSA KEY\n");
printf("p=%i\n",p_key);
printf("q=%i\n",q_key);
printf("n=%u\n",n_key);
printf("e=%i\n",e_key);
printf("d=%u\n",d_key);
printf("\nIf You want this key Enter \"1\" else Enter \"0\" ");
scanf("%i",&TAK_NI);
if(TAK_NI==0)
{
printf("p=");
scanf("%i",&p_key);
printf("\nq=");
scanf("%i",&q_key);
n_key=p_key*q_key;
Ojler_Function=(p_key-1)*(q_key-1);
printf("\ne=");
scanf("%i",&e_key);
d_key=ReverseEvklid(Ojler_Function,e_key);
printf("\nd=%i\n",d_key);
}
source=fopen("c:\\zasch.txt","rb");
zasch = fopen("C:\\rozsch.txt","wb");
while(!feof(source))
{
if(s==0)
{
M=Y>>(f-z);
Y=Y<<z;
if(l>0)
{
s=1;
}
else
{
l=z+l;
}
}
else
{
Y=Y>>(f-z);
fread(&x,2,1,source);
xx=x>>(f-l);
M=((Y|xx));
Y=x<<l;
l=(z-(f-l));
if(l<=0)
{
s=0;
l=z+l;
}
}
/******************************************************************/
for(i=0;i<N_ALF;i++)
if(M==ALFAVIT[i])
{
position=i;
break;
}
position_new=position;
MWRITE=ALFAVIT[position_new];
printf("M=%u\n",M);
printf("MWRITE=%u\n",MWRITE);
/******************************************************************/
label1:
if(sw==0)
{
if(Vubir%2==1)
{
C_HIGH=C;
kk+=1;
}
else
{
kk+=1;
C_LOW=C;
}
if(kk==2)
{
printf("WRITE TWO BYTES\n");
printf("C_LOW=%u\n",C_LOW);
printf("C_HIGH=%u\n\n",C_HIGH);
fwrite(&C_LOW,1,1,zasch);
fwrite(&C_HIGH,1,1,zasch);
kk=0;
}
C=(YW>>(fw-zw));
YW=YW<<zw;
Vubir+=1;
if(lw>0)
{
sw=1;
}
else
{
lw=zw+lw;
}
}
else
{
YW=YW>>(fw-zw);
xxw=MWRITE>>(fw-lw);
C=(YW|xxw);
Vubir+=1;
YW=((MWRITE<<lw));
lw=(zw-(fw-lw));
if(lw<=0)
{
sw=0;
lw=zw+lw;
goto label1;
}
}
if(Vubir%2==1)
{
C_HIGH=C;
kk+=1;
}
else
{
kk+=1;
C_LOW=C;
}
if(kk==2)
{
printf("WRITE TWO BYTES\n");
printf("C_LOW=%u\n",C_LOW);
printf("C_HIGH=%u\n\n",C_HIGH);
fwrite(&C_LOW,1,1,zasch);
fwrite(&C_HIGH,1,1,zasch);
kk=0;
}
}
fclose(source);
fclose(zasch);
system("PAUSE");
return 0;
}
Результат
Вміст файлу c:\\bin.txt
RSA схему шифрування було запропоновано у 1978 році та названо іменами трьох його винахідників: Роном Рівестом (Ron Rivest), Аді Шаміром (Adi Shamir) та Леонардом Адлеманом (Leonard Adleman). RSA належить до класу алгоритмів кодування з відкритим ключем.
У 80-х роках криптосистема переважно використовувалася для забезпечення секретності та достовірності цифрових даних. У сучасному світі RSA використовується в web – серверах та браузерах для зберігання таємності даних що передаються по мережі, .
Схема RSA базується на обчисленні виразів зі степенями. Відкритий текст шифрується блоками, довжина кожного із яких менша за деяке число n.
Вміст файлу С:\\zasch.txt
шaо5*™—юWPµyZz'P…ОЇWЩ‡·ЩN>Н”,я‡{t'ivY=<є‚O6sw=“рkZф(‡TPЃ0ОN‰ҐЭxњЩ‡)ђ#ФхT=
сИPХјо_7г·19“;^=јђ80·iЉAІmCп”ЭN…Іw6јu7]Ѓ8ЪTоа@X|-ђЇщГе¤H‚iИО%ЛUЃtґќђVпGЃ;¶ЋћУЄє!-"6]
i‰WYvюЊпИNfКnP™vЧNАEк*u7Hіс”%QЃе=А…d8FЭ(хЫ=]т\… Л6P‰кmЧ„Иp8=5зIЗВ‡Л/ЕN),AЛжЦµi6ЬбtNЃфр0ђПZфп(;a8зч”%»ЛµАЧy{ VsT=ЏґrЕNўS¶Q5I¶ФTМT7:µ‡ЪЛRкxц0ќi7OyЄuh¦Є±]q
PЛЕЧP!mV;ЂЏЮр~пV•Щ{Л(Ыyп–Nsa6ю|п_oБyP—фttL\ґPKrхХ-Фёп:]¦Т8Фќ)t‘HДЛ260МОЏЇОqтўG”хђЬPШќґ0LМuИ¦ЄІ]l~QPU#/W±0tOќD•µі›Ь·‹T=мрЄ0tЋ–y§ќ5ЏГОпюeЉЖVЫ}L\ґPKrKЦH·…ЩGKqЛШ(ччЬuОxаЪvЋІ]бМФМЗ*тФп*•нgTPМjпBO7•”=yЬP«DЬщЇAr`O…jЃ&+=lчjГD§H(u‡ГяП,к2rАI\Ф(Zv}ТNј`72¦тждiЖњ°ѓ
ВИСНОВКИ:
Відомо два основні типи алгоритмів заснованих на застозуваннні ключів : симетричні та асиметричні. Симетричні алгоритми є алгоритмами з таємним ключем. При використанні даних алгоритмів необхідно щоб дві сторони, які хочуть обмінюватись інформацією узгодили між собою єдиний таємний для суперника ключ. Асиметричні алгоритми є алгоритмами з відкритим публічним ключем. Вони передбачають наявність двох різних ключів: відкритого ключа зашифрування, і закритого ключа розшифрування. Ключ розшифрування не можливо або дуже тяжко обчислити знаючи ключ зашифрування. Щоб знайти ключ розшифрування необхідно знайти обернене значенння важкооборотної фунції. У системі RSA це розкласти на множники ключ n, щоб знайти p та q, з яких далі обчислити ключ розшифрування d. Асиметричні шифри є надійнішими за симетричні. Але їх недоліком є низька швидкодія.
ВИКОРИСТАНА ЛІТЕРАТУРА
1. Джонс Брэдли, Эйткен Питер. Освой самостоятельно С за 21 день, 6-е издание. : Пер с англ. – М. : Издательский дом “Вильямс”,
2005. – 800 с.
С. Коутинхо. Введение в теорию чисел. Алгоритм RSA. Москва: Постмаркет, 2001. – 328 с.
Фергюсон Нильс, Шнайер Брюс. Практическая криптография.
: Пер. с англ. – М. : Издательский дом “Вильямс”, 2005. – 424 с.
О. В. Вербіцький. Вступ до криптології. Львів., “ВНЛТ”,1998.