Міністерство освіти і науки України
Національний університет «Львівська політехніка»
Кафедра ЕОМ
Лабораторна робота №4
«Електронний цифровий «конверт»
Львів-2006
1.Мета: засвоїти принцип роботи електронного цифрового конверта.
2.Теоретична частина:
Головна перевага асиметричних криптосистем з відкритим ключем – їх потенціально висока безпека: нема необхідності ані повідомляти нікому значення секретних ключів, ані переконувати в їх автентичність. Але швидкодія асиметричних криптосистем з відкритим ключем звичайно в сотні, а то і в більше разів менше швидкодії симетричних криптосистем з секретним ключем.
В свою чергу, швидкодіючі симетричні криптосистеми володіють значним недоліком: секретний ключ симетричної криптосистеми, що оновлюється, повинен регулярно передаватися партнерам по інформаційному обміну, і під час цих передач виникає небезпека розкриття секретного ключа.
Існує ефективний метод комбінованого використання симетричного та асиметричного шифрування. Комбінований (гібридний) метод шифрування дозволяє сполучати переваги високої секретності, що надаються асиметричними криптосистемами з відкритим ключем, з перевагами високої швидкості роботи, які притаманні симетричним криптосистемам з секретним ключем.
При такому підході симетричну криптосистему застосовують для шифрування вхідного відкритого тексту, а асиметричну криптосистему з відкритим ключем – тільки для шифрування секретного ключа симетричної криптосистеми. В результаті асиметрична криптосистема з відкритим ключем не заміняє, а лише доповнює симетричну криптосистему з секретним ключем, дозволяючи підвищити в цілому захищеність інформації, що передається. Такий підхід іноді називають схемою електронного цифрового «конверта».
Припустимо, користувач А хоче використати комбінований метод шифрування для захищеної передачі повідомлення М користувачу В. Тоді порядок дій користувачів буде наступним:
Користувач А:
Створює (наприклад, генерує випадковим чином) симетричний сеансовий секретний ключ KS.
Зашифровує повідомлення М з допомогою симетричного сеансового секретного ключа КS.
Зашифровує секретний сеансовий ключ КS на відкритому ключі КВ користувача В.
Передає по відкритому каналу зв’язку по адресі користувача В зашифроване повідомлення М разом з зашифрованим сеансовий ключем КS.
Після отримання електронного цифрового «конверта» - зашифрованих повідомлення М і сеансового ключа КS – користувач В:
Розшифровує на своєму секретному ключі КВ сеансовий ключ КS.
З допомогою отриманого сеансового ключа КS розшифровує повідомлення М.
Отриманий електронний цифровий «конверт» може розкрити тільки законний одержувач – користувач В. Тільки він, володіючи особистим секретним ключем КВ, зможе правильно розшифрувати секретний сеансовий ключ КS і потім з його допомогою розшифрувати та прочитати отримане повідомлення М.
При методі цифрового «конверта» недоліки симетричного і асиметричного криптоалгоритма компенсуються наступним чином:
проблема поширення ключів симетричного криптоалгоритма усувається за рахунок того, що сеансовий ключ КS, на якому шифруються власне повідомлення, передається по відкритому каналу зв’язку в зашифрованому вигляді. Для шифрування ключа КS використовується асиметричний криптоалгоритма;
проблеми повільної швидкості асиметричного шифрування у даному випадку практично не виникає, оскільки асиметричний криптоалгоритма шифрує лише короткий ключ КS, а всі дані шифрується швидким симетричним криптоалгоритмом. В результаті отримують швидке шифрування в сполученні із зручним розподілом ключів.
Вибір довжин ключів для кожного типу криптосистеми слід здійснювати таким чином, щоб зловмиснику було однаково важко атакувати будь-який механізм захисту комбінованої криптосистеми.
В таблиці наведені поширені довжини ключів симетричних та асиметричних криптосистем, для яких важкість атаки повного перебору приблизно дорівнює важкості факторизації відповідних модулів асиметричних криптосистем.
Якщо використовується короткий сеансовий ключ (наприклад, 40-бітовий DES), то немає значення, наскільки великими є асиметричні ключі. Хакери будуть атакувати не їх, а сеансові ключі.
Таблиця. Довжини ключів для симетричних та асиметричних криптосистем при однаковій їх крипостійкості.
Довжина ключа
симетричної
криптосистеми,
біт
Довжина ключа
асиметричної
криптосистеми,
біт
56
384
64
512
80
768
112
1792
128
2304
3.Текст програми:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include<math.h>
#include<stdlib.h>
#include <time.h>
#include<fstream.h>
#include<stdio.h>
#include<alloc.h>
#include "Main.h"
//#include "cast_sboxes.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
bool Ed1=false;
bool Ed2=false;
int LowValue=0;
int HighValue=0;
int openKey1,openKey2,closeKey;
unsigned int * de_hash;
unsigned int * signature;
unsigned int * hash;
String Coded,UnCoded,str1,str2,tmp;
int i;
cast_key key;
u8 a[16],b[16];
//---------------------------------------------------------------------------
// Початкові ініціалізації
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{ Blockage();
}
//---------------------------------------------------------------------------
// Обчислення простого числа за допомогою решета Ератосфена
int TForm1::SimpleCalculation(int first, int second)
{ int p,q,n,F,e,d,result=0;
int i=0,r=1;
p=SimpleNum(first,second);
Memo1->Lines->Add("Перше просте число p:");
Memo1->Lines->Add(p);
Edit3->Text=IntToStr(p);
do q=SimpleNum(first,second);
while(q==p);
Memo1->Lines->Add("Друге просте число q:");
Memo1->Lines->Add(q);
Edit4->Text=IntToStr(q);
n=p*q;
openKey2=n;
Memo1->Lines->Add("Їх добуток або один з відкритих ключів n:");
Memo1->Lines->Add(n);
Edit5->Text=IntToStr(n);
F=(p-1)*(q-1);
Memo1->Lines->Add("Обчислюється добуток F=(p-1)*(q-1):");
Memo1->Lines->Add(F);
while(n)
{ n/=10;
i++;
}
while(i!=1)
{ r*=10;
i--;
}
do {
do { e=SimpleNum (r,F);
} while (HCD(F,e)!=1);
openKey1=e;
d=Diafant(e,F,0,1,1,0);
} while((((e*d)%F)!=1)||(d<0));
Memo1->Lines->Add("Другий відкритий ключ e:");
Memo1->Lines->Add(e);
Memo1->Lines->Add("Закритий ключ:");
Memo1->Lines->Add(d);
closeKey=d;
Edit6->Text=IntToStr(e);
Edit7->Text=IntToStr(d);
Button2->Enabled=true;
return result;
}
//---------------------------------------------------------------------------
// Обчислення випадкового числа в межах
int TForm1::SimpleNum(int Low, int High)
{ int r;
int i;
time_t t;
srand((unsigned)time(&t));
while(t)
{ r=rand();
r%=High;
if((r/Low) != 0)
{ for (i=r-1;i>1;i--)
if((r%i)==0)break;
if(i==1) break;
}
}
return r;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{ LowValue=StrToInt(Edit1->Text);
HighValue=StrToInt(Edit2->Text);
if ((LowValue >= 2)&&(HighValue > 2)&&(LowValue<=HighValue))
SimpleCalculation(LowValue, HighValue);
else MessageBox(NULL,"Неправильно введені межі для формування простих чисел!","Помилка",MB_ICONWARNING);
}
//---------------------------------------------------------------------------
int TForm1::HCD(int a, int b)
{ int r0=a;
int r1=b;
int temp;
while(r1!=0)
{
temp=r0%r1;
r0=r1;
r1=temp;
}
return r0;
}
//---------------------------------------------------------------------------
int TForm1::Diafant(int a, int b, int P2, int P1, int Q2, int Q1)
{ int r0,r1;
int q,P,Q,c,y;
static int k=-1;
r0=a;r1=b;
q=r0/r1;
P=q*P1+P2;
Q=q*Q1+Q2;
c=r0%r1;
if (c!=0) { y=Diafant(r1,c,P1,P,Q1,Q); k++; }
else y=Q1*pow(-1,k-1) ;
return y;
}
//---------------------------------------------------------------------------
int* TForm1::encode(int* msg,int length)
{ int* enc;
enc = (int*) calloc(length,sizeof(int));
for(int i = 0; i < length; i++)
enc[i] = LR_bin_exp(msg[i],openKey1,openKey2);
return enc;
}
//----------------------------------------
int* TForm1::decode(int* msg,int length)
{ int *dec;
dec = (int*) calloc(length,sizeof(int));
for(int i = 0; i < length; i++)
dec[i] = LR_bin_exp(msg[i],closeKey,openKey2);
return dec;
}
//----------------------------------------
int TForm1::LR_bin_exp(int x, int n,int m)
{ int test = 0x40000000,y = 1;
for(int i = 30; i >= 0; i--, test >>= 1)
{ y = y * y % m;
if (n & test)
y = y * x % m;
}
return y;
}
//------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{ Button1->Enabled=false;
str1=Edit8->Text;
str2=Edit10->Text;
for(i=0;i<16;i++)
a[i]=str1[i+1];
for(i=0;i<16;i++)
b[i]=str2[i+1];
Memo1->Lines->Add("Кодуємо повідомлення");
for (i = 0; i < 1000000; i++) {
/* aL = encrypt(aL,b); aR = encrypt(aR,b); */
cast_setkey(&key, b, 16);
cast_encrypt(&key, &a[0], &a[0]);
cast_encrypt(&key, &a[8], &a[8]);
/* bL = encrypt(bL,a); bR = encrypt(bR,a); */
cast_setkey(&key, a, 16);
cast_encrypt(&key, &b[0], &b[0]);
cast_encrypt(&key, &b[8], &b[8]);
}
//Memo1->Lines->Add("a= ");
//for (i = 0; i < 16; i++)
// str1[i+1]=a[i];
//Memo1->Lines->Add(str1);
Memo1->Lines->Add("Закодоване повідомлення");
for (i = 0; i < 16; i++)
str2[i+1]=b[i];
Memo1->Lines->Add(str2);
int len,len1;
String str;
unsigned char * InStr;
int * NumStr;
int * EncodeStr;
str=Edit8->Text;
len=16;
InStr = new unsigned char[2*len];
NumStr = new int[len];
EncodeStr = new int[len];
strncpy(InStr, str.c_str(),2*len);
//NumStr = StrToIntM(InStr,len);
EncodeStr = encode(NumStr,len);
AnsiString tempStr;
for(int i = 0; i < len; i++)
tempStr += IntToHex(abs(EncodeStr[i]),4) ;
Memo1->Lines->Add("Закодований ключ");
Memo1->Lines->Add(tempStr);
Coded=tempStr;
delete InStr;
delete NumStr;
delete EncodeStr;
Button2->Enabled=false;
Button3->Enabled=true;
}
//---------------------------------------------------------------------------
AnsiString TForm1::convert(unsigned long num)
{ unsigned long temp = 0;
for (int i=0; i < 4; i++)
((char*)(&temp))[i] = ((char*)(&num)) [3-i];
return IntToHex((int)temp,8);
}
//--------------------------------------------------
int* TForm1::StrToIntM(const unsigned char * str, int len)
{ int* temp;
temp = new int[len];
char t[3] = {0,0,0};
for(int i = 0; i < len; i++)
{ t[0] = str[2*i];
t[1] = str[2*i+1];
temp[i] = StrToInt("0x" + AnsiString(t));
}
return temp;
}
//--------------------------------------------------
int* TForm1::StrToIntM4(unsigned char * str, int len)
{ int* temp;
temp = new int[len];
char t[5] = {0,0,0,0,0};
for(int i = 0; i < len; i++)
{ t[0] = str[4*i];
t[1] = str[4*i+1];
t[2] = str[4*i+2];
t[3] = str[4*i+3];
temp[i] = StrToInt("0x" + AnsiString(t));
}
return temp;
}
//--------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{ //----- Декодування ключа --------------------
unsigned char * InStr2;
int * NumStr;
int * DecodeStr;
int len = 16 ;
InStr2 = new unsigned char[4*len];
NumStr = new int[len];
DecodeStr = new int[len];
strncpy(InStr2,Coded.c_str() ,4 * len);
NumStr = StrToIntM4(InStr2,len);
DecodeStr = decode(NumStr , len);
AnsiString tempStr="";
Memo1->Lines->Add("Розкодований ключ");
Memo1->Lines->Add(tempStr);
delete InStr2;
delete NumStr;
delete DecodeStr;
for (i = 0; i < 1000000; i++) {
/* bL = decrypt(bL,a); bR = decrypt(bR,a); */
cast_setkey(&key, a, 16);
cast_decrypt(&key, &b[0], &b[0]);
cast_decrypt(&key, &b[8], &b[8]);
/* aL = decrypt(aL,b); aR = decrypt(aR,b); */
cast_setkey(&key, b, 16);
cast_decrypt(&key, &a[0], &a[0]);
cast_decrypt(&key, &a[8], &a[8]);
}
for (i = 0; i < 16; i++)
str1[i+1]=a[i];
Edit9->Text=str1;
Memo1->Lines->Add("Розкодоване повідомлення");
for (i = 0; i < 16; i++)
str2[i+1]=b[i];
Edit11->Text=str2;
Memo1->Lines->Add(str2);
Blockage();
}
//---------------------------------------------------------------------------
// Початок нового сеансу
void __fastcall TForm1::Button4Click(TObject *Sender)
{ UnBlocking();
}
//---------------------------------------------------------------------------
// Блокування всіх контролів
void TForm1::Blockage()
{ UpDown1->Enabled=false;
UpDown2->Enabled=false;
Edit1->Enabled=false;
Edit2->Enabled=false;
Edit8->Enabled=false;
Edit9->Enabled=false;
Edit10->Enabled=false;
Edit11->Enabled=false;
//---Кнопки не доступні------
Button1->Enabled=false;
Button2->Enabled=false;
Button3->Enabled=false;
Button4->Enabled=true;
}
//---------------------------------------------------------------------------
// Розблокування всіх контролів
void TForm1::UnBlocking()
{ Edit1->Text="2";
Edit2->Text="2";
Edit3->Text="";
Edit4->Text="";
Edit5->Text="";
Edit6->Text="";
Edit7->Text="";
//Edit8->Text="";
Edit9->Text="";
//Edit10->Text="";
Edit11->Text="";
UpDown1->Enabled=true;
UpDown2->Enabled=true;
Edit1->Enabled=true;
Edit2->Enabled=true;
Edit8->Enabled=true;
Edit9->Enabled=true;
Edit10->Enabled=true;
Edit11->Enabled=true;
//---Кнопки не доступні------
Button1->Enabled=true;
Button2->Enabled=false;
Button3->Enabled=false;
Button4->Enabled=true;
Memo1->Lines->Clear();
}
//---------------------------------------------------------------------------
4.Приклад виконання:
5.Висновок: в процесі виконання лабораторної роботи я засвоїв принцип роботи електронного цифрового конверта.