В данном разделе курсового проекта приводится описание программного продукта, реализующего алгоритм шифрования DES: показывается логика работы программы, описываются процедуры и функции.
Программа “Research DES” написана на языке программирования высокого уровня C++; при разработке использовалась среда Borland C++ Builder. Исходный текст программы приведен в приложении 1.
Программа представляет собой приложение для операционной системы Windows, которое выполняется следующим образом: пользователь выбирает файл, который содержит необходимое для шифрования сообщение. Получив имя файла, программа открывает его, производит необходимые действия над данными, и записывает полученный результат в нужный пользователю файл.
Предлагаемый программный продукт содержит следующие компоненты:
а) Основной файл mainform.cpp.
б) Алгоритм преобразования исходного сообщения.
в) Алгоритм преобразования входных данных.
Пользователю предлагается ввести ключ, который может быть представлен в двоичном, шестнадцатеричном или текстовом виде. Затем необходимо выбрать источник данных: файл или строка. При шифровании строки, пользователь вводит необходимую информацию, и нажимает кнопку «старт». Вывод зашифрованной информации осуществляется в свободное поле. При шифровании файла, пользователь указывает необходимый файл, выбирает конечный файл и нажимает кнопку «старт». Зашифрованная информация записывается в указанный пользователем конечный файл.
Заключение
В процессе разработки курсового проекта были получены навыки работы и программирования приложений на языке C++ в среде Borland C++ 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)"Данные успешно записаны в файл\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)
"Не удается прочитать данные из файла:\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)
"Не удается записать данные в файл:\n" + FileName).c_str(),
"Ошибка записи файла",
MB_ICONERROR | MB_OK);
return false;
}
return true;
}
Листинг программы А.2 –des.cpp
#include <vcl.h>
#pragma hdrstop
#include "DES.h"
#pragma package(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 элементов (сдвиг ключа) на \
//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)
{
int S_inp;//6 бит, подающиеся на вход в S-блок
int S_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]; //Ключ без битов четности
unsigned char Li[4]; //сохраненная левая половина данных
unsigned char small_key[6]; //ключ после перестановки со сжатием
unsigned char big_data[6]; //данные после перестановки с расширением
unsigned char small_data[4]; //данные после подстановки с помощью
//S-блоков
//Перестановка ключа (+ избавление от 8х битов)
transposition (key, i_key, table_key_initial_transposition, 56);
//Первоначальная перестановка данных
transposition (data, NULL, table_initial_transposition, 64);
for (int i=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);
}
Размещено на Allbest.ru