Смекни!
smekni.com

Программная реализация алгоритма шифрования DES. Режим ECB (стр. 3 из 3)


Заключение

В процессе разработки курсового проекта были получены навыки работы и программирования приложений на языке C++ в среде BorlandC++ Builder. В результате работы над проектом получена работоспособная программа, реализующая шифрование по алгоритму DESв режиме «электронная кодовая книга». Данный продукт может использоваться как учебное пособие, или для домашнего пользования. Симметричные алгоритмы шифрования еще долго будут актуальны.

Список использованных источников

1. Ю.В.Романец, П.А. Тимофеев, В.Ф. Шаньгин Защита информации в компьютерных системах и сетях: Радио и связь: Москва, 1999. - 328 с.

2 Брюс Шнайер, Прикладная криптография: БХВ-Питер: Санкт-Петербург,2004.-718 с.

Приложение А

Листинг программы А.1 –mainform.cpp

#include <vcl.h>

#pragma hdrstop

#include "DESAlgorithms.h"

#include "MainForm.h"

#pragma package(smart_init)

#pragma link "SHDocVw_OCX"

#pragma link "DataFrame"

#pragma resource "*.dfm"

TMainDialogForm *MainDialogForm;

__fastcall TMainDialogForm::TMainDialogForm(TComponent* Owner)

: TForm(Owner)

{

KeysDataFrame->EditLeft = 80;

KeysDataFrame->AddField("Ключ", false);

SrcDataFrame->EditLeft = 100;

SrcDataFrame->AddField("Входнаястрока", false);

SrcDataFrame->AddField("Результат", true);

}

void __fastcall TMainDialogForm::BrowseInpFilePathButtonClick(TObject *Sender)

{

if (OpenDialog->Execute()) InpFilePathEdit->Text = OpenDialog->FileName;

}

void __fastcall TMainDialogForm::BrowsOutFilePathButtonClick(

TObject *Sender)

{

if (SaveDialog->Execute()) OutFilePathEdit->Text = SaveDialog->FileName;

}

void __fastcall TMainDialogForm::AutoStartButtonClick(TObject *Sender)

{

DESAlg.Key = KeysDataFrame->Field["Ключ"];

if ( IsCryptRadioButton->Checked ) DESAlg.Crypt = true;

else DESAlg.Crypt = false;

if (SourcePageControl->ActivePage == StringSrcSheet) {

//Входные данные берем из строки "Входная строка"

DESAlg.Data = SrcDataFrame-> Field["Входная строка"];

}

else if (SourcePageControl->ActivePage == FileSrcSheet) {

//Входные данные берем из файла, путь к которому находится в

//InpFilePathEdit

DESAlg.Data = ReadAnsiStringFromFile( InpFilePathEdit->Text );

}

DESAlg.Exectute();

if (SourcePageControl->ActivePage == StringSrcSheet) {

SrcDataFrame->Field["Результат"] = DESAlg.Data;

}

else if (SourcePageControl->ActivePage == FileSrcSheet) {

//Выходные данные записываем в файл, путь к которому находится в

//OutFilePathEdit

if (WriteAnsiStringToFile( DESAlg.Data, OutFilePathEdit->Text )) {

MessageBox(this->Handle,

((AnsiString)"Данныеуспешнозаписанывфайл&bsol;n" +

OutFilePathEdit->Text).c_str(), this->Caption.c_str(),

MB_ICONINFORMATION | MB_OK );

}

}

}

//ЧтениефайлавAnsiString

AnsiString __fastcall TMainDialogForm::ReadAnsiStringFromFile(

AnsiString FileName)

{

AnsiString Result;

try {

TFileStream *in = new TFileStream(FileName, fmOpenRead); //открываемфайл

if( in != NULL ) {

int size = in->Size;

if( size != 0 ) {

try {

Result.SetLength(size);

in->Read((void *)(Result.data()), size);

}

catch( EOutOfMemory& ) {}

delete in;

}

}

}

catch ( EStreamError& ) {

MessageBox(this->Handle, ( (AnsiString)

"Не удается прочитать данные из файла:&bsol;n" + FileName).c_str(),

"Ошибка чтения файла", MB_ICONERROR| MB_OK);

return "";

}

return Result;

}

//ЗаписьвфайлизAnsiString

bool __fastcall TMainDialogForm::WriteAnsiStringToFile(AnsiString String,

AnsiString FileName)

{

try {

TFileStream *out = new TFileStream(FileName, fmCreate); // открываемфайл

if( out != NULL ) {

if( String.Length() != 0 ) {

try {

out->Write((void *)(String.data()), String.Length());

}

catch( EOutOfMemory& ) {}

delete out;

}

}

}

catch (EStreamError&) {

MessageBox(this->Handle, ((AnsiString)

"Неудаетсязаписатьданныевфайл:&bsol;n" + FileName).c_str(),

"Ошибказаписифайла",

MB_ICONERROR | MB_OK );

return false;

}

return true;

}

ЛистингпрограммыА.2 –des.cpp

#include <vcl.h>

#pragma hdrstop

#include "DES.h"

#pragmapackage(smart_init)

//Извлечение бита из массива символов

int get_bit (unsigned char *data, int num)

{

return (int)((data[num/8] & (1 << (7 - (num % 8)))) != 0);

}

//Установкабитавмассивесимволов

void set_bit (unsigned char *data, int num, int bit)

{

if(bit== 1)//Нужно бит установить в 1

data[num/8] |= 1 << (7 - (num% 8));

else//Нужно бит сбросить в 0

data[num/8] &= ~(1 << (7 - (num% 8)));

}

//Циклический сдвиг влево массива dataиз num_elemэлементов на num_shift

//позиций

void shift_left (unsigned char *data, int num_elem, int num_shift)

{

int save_bit;

for (int k=0; k < num_shift; ++k)

{

save_bit = get_bit(data, 0);

for (int i=0; i < num_elem - 1; ++i)

{

data[i] <<= 1;

set_bit(&data[i], 7, get_bit(&data[i+1], 0));

}

data[num_elem-1] <<=1;

set_bit (&data[num_elem-1], 7, save_bit);

}

}

//Циклический сдвиг вправо массива dataиз num_elemэлементов на num_shift

//позиций

void shift_right (unsigned char *data, int num_elem, int num_shift)

{

int save_bit;

for (int k=0; k < num_shift; ++k)

{

save_bit = get_bit(&data[num_elem-1], 7);

for (int i=num_elem - 1; i >= 1 ; --i)

{

data[i] >>= 1;

set_bit(&data[i], 0, get_bit(&data[i-1], 7));

}

data[0] >>=1;

set_bit (&data[0], 0, save_bit);

}

}

//Циклический сдвиг влево массива dataиз 28 элементов (сдвиг ключа) на &bsol;

//num_shift позиций

void shift_left_key (unsigned char *key, int num_shift)

{

int save_bit;

for (int i=0; i<num_shift; ++i)

{

shift_left(key, 7, 1);

save_bit=get_bit(key, 27);

set_bit(key, 27, get_bit(key, 55));

set_bit(key, 55, save_bit);

}

}

//Циклический сдвиг влево массива dataиз 28 элементов (сдвиг ключа) на

//num_shift позиций

void shift_right_key (unsigned char *key, int num_shift)

{

int save_bit;

for (int i=0; i<num_shift; ++i)

{

shift_right(key, 7, 1);

save_bit=get_bit(key, 0);

set_bit(key, 0, get_bit(key, 28));

set_bit(key, 28, save_bit);

}

}

//Обменивает биты в соответсвии с таблицами перестановки

//data_src- входной массив данных. Если NULLтогда данные берутся из data_des

//data_des- входной/выходной массив данных.

//transposition_table - таблицаперестановки

//num - кол-воэлементов/ 8 вdata_des иэлементоввtransposition_table

void transposition (unsigned char *data_des, unsigned char *data_src,

int *transposition_table, int num)

{

bool delete_mem=false;

if (data_src==NULL)

{

data_src = new unsigned char[num / 8];

memcpy(data_src, data_des, num / 8);

delete_mem=true;

}

for (int i=0; i<num; ++i)

set_bit(data_des, i, get_bit(data_src, transposition_table[i] - 1));

if (delete_mem) delete [] data_src;

}

//Возвращает значение S-подстановки

int get_S_substitution (int inp, int *S_table)

{

int string=0;//Строкавтаблице

int column=0;//Столбецвтаблице

string = get_bit((unsigned char*)(&inp), 2) |

get_bit((unsigned char *)(&inp), 5) << 1 ;

column = get_bit((unsigned char*)(&inp), 3) |

get_bit((unsigned char *)(&inp), 4) << 1 |

get_bit((unsigned char *)(&inp), 5) << 2 |

get_bit((unsigned char *)(&inp), 6) << 3;

return S_table[string * 16 + column];

}

//РеализуеталгоритмподстановкиS-блоков

void S_block (unsigned char *dest, unsigned char *src)

{

intS_inp;//6 бит, подающиеся на вход в S-блок

intS_out;//4 бита, получаемые из S-блока

for (int i=0; i<4; ++i) dest[i]=0;

for (int i=0; i<8; ++i)

{

shift_left (src, 6, i);

S_inp=(src[0] >> 2) & 0x3F;

S_out=get_S_substitution(S_inp, table_S_block[i]);

dest[i/2] |= S_out << (((i + 1) % 2) * 4);

}

}

//Сам алгоритм DES. i_key- 64 бита (8 байт) (с битами четности); data- 64 бита

//Алгоритм используется как при шифровании, так и при дешифровании. Ключ при

//дешифровании менять самим. При decode==false- зашифровка, если ==true-

//расшифровка

void DES_algorithm (unsigned char *i_key, unsigned char *data,

bool decode=false)

{

unsigned char key[7]; //Ключбезбитовчетности

unsignedcharLi[4]; //сохраненная левая половина данных

unsignedcharsmall_key[6]; //ключ после перестановки со сжатием

unsignedcharbig_data[6]; //данные после перестановки с расширением

unsignedcharsmall_data[4]; //данные после подстановки с помощью

//S-блоков

//Перестановка ключа (+ избавление от 8х битов)

transposition (key, i_key, table_key_initial_transposition, 56);

//Первоначальная перестановка данных

transposition (data, NULL, table_initial_transposition, 64);

for(inti=0; i<16; ++i)

{

//Сохранение Li(берется из правой части)

memcpy(Li, &data[4], 4);

//Сдвигключа

if (!decode)

{

shift_left_key (key, table_shift_key[i]); //При зашифровке

}

else

{

shift_right_key (key, table_shift_key_right[i]); //При расшифровке

}

//Перестановка ключа со сжатием

transposition (small_key, key,

table_transposition_with_compression, 48);

//Перестановка данных с расширением

transposition(big_data, &data[4],

table_transposition_with_extension, 48);

//Сложение данных XOR с ключом

for (int k=0; k<6; ++k)big_data[k]^=small_key[k];

//ПодстановкаспомощьюS-блоков

S_block (small_data, big_data);

//Перестановка данных с помощью P-блоков

transposition (small_data, NULL, table_transposition_P_block, 32);

//Сложение XORданных левой и правой частей

for (int k=0; k<4; ++k) small_data[k] ^= data[k];

//Запись в dataполученных результатов

memcpy(&data[0], Li, 4);

memcpy(&data[4], small_data, 4);

}

//Заключительный обмен полученных результатов

memcpy(Li, &data[0], 4);

memcpy(&data[0], &data[4], 4);

memcpy(&data[4], Li, 4);

//Заключительная перестановка

transposition (data, NULL, table_final_transposition, 64);

}