Лабораторная работа № 1
Защита от разрушающих программных воздействий, защита
программ от изменения и контроль целостности
Тула 2015
1. Цель работы
Познакомиться с общими принципами защиты программного
обеспечения и способами организации контроля целостности исполняемых
модулей и важных программных данных.
2. Задание на работу
Вариант № 3. Контроль целостности программных данных (данные
неизменны).
3. Теоретическая справка
Основным методом борьбы с модификацией программного
обеспечения является контроль целостности. Реализация этого может быть
достигнута методами проверки контрольной суммы и цифровой подписью.
4. Ход работы
В программной реализации системы контроля целостности участвуют
следующие проекты:
1. Приложение для проверки контрольной суммы входного файла по
алгоритму MD5.
2. Приложение для подсчета контрольной суммы входного файла по
алгоритму: сумма по модулю 216 всех пар байт исходного файла (значение
хеш-кода используется при формировании и проверке цифровой подписи).
5
3. Приложение для формирования открытых и закрытых ключей
цифровой подписи.
4. Приложение для формирования присоединяемой к файлу цифровой
подписи по алгоритму DSA.
5. Приложение для проверки присоединяемой цифровой подписи.
Программа 1
// pasoib_1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "md5.h"
using namespace std;
FILE *file;
char x1;
file=fopen(p, "rb+");
long size;
fseek(file, 0, SEEK_END);
size=ftell(file);
fseek(file, 0, SEEK_SET);
char* mass;
mass=new char[size];
fclose(file);
6
return 0;
}
Файл md5.h:
#include "stdafx.h"
using namespace std;
#ifdef __alpha
typedef unsigned int UINT4;
#else
typedef unsigned long int UINT4;
#endif
void MD5Init(void);
void MD5Update(unsigned char *bug, unsigned int len);
void MD5Final(char* cReturnStr);
void Transform(UINT4 *buf, UINT4 *in);
7
}
#define II(a, b, c, d, x, s, ac) \
{(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
m_lMD5[0] = MD5_INIT_STATE_0;
m_lMD5[1] = MD5_INIT_STATE_1;
m_lMD5[2] = MD5_INIT_STATE_2;
m_lMD5[3] = MD5_INIT_STATE_3;
}
while (inLen--)
{
m_lpszBuffer[mdi++] = *inBuf++;
if (mdi == 0x40)
8
{
for (i = 0, ii = 0; i < 16; i++, ii += 4)
in[i] = (((UINT4)m_lpszBuffer[ii+3]) << 24) |
(((UINT4)m_lpszBuffer[ii+2]) << 16) |
(((UINT4)m_lpszBuffer[ii+1]) << 8) |
((UINT4)m_lpszBuffer[ii]);
Transform (m_lMD5, in);
mdi = 0;
}
}
}
cReturnStr[0]='\0';
if (lpszMD5[i] == 0)
{
temp[0] = '0';
temp[1]='0';
}
else if (lpszMD5[i] <= 15)
{
sprintf(temp,"0%x",lpszMD5[i]);
}
else
{
sprintf(temp,"%x",lpszMD5[i]);
}
strcat(cReturnStr,temp);
}
lpszMD5[0]='\0';
}
#define S11 7
#define S12 12
#define S13 17
9
#define S14 22
FF ( a, b, c, d, in[ 0], S11, 0xD76AA478L);
FF ( d, a, b, c, in[ 1], S12, 0xE8C7B756L);
FF ( c, d, a, b, in[ 2], S13, 0x242070DBL);
FF ( b, c, d, a, in[ 3], S14, 0xC1BDCEEEL);
FF ( a, b, c, d, in[ 4], S11, 0xF57C0FAFL);
FF ( d, a, b, c, in[ 5], S12, 0x4787C62AL);
FF ( c, d, a, b, in[ 6], S13, 0xA8304613L);
FF ( b, c, d, a, in[ 7], S14, 0xFD469501L);
FF ( a, b, c, d, in[ 8], S11, 0x698098D8L);
FF ( d, a, b, c, in[ 9], S12, 0x8B44F7AFL);
FF ( c, d, a, b, in[10], S13, 0xFFFF5BB1L);
FF ( b, c, d, a, in[11], S14, 0x895CD7BEL);
FF ( a, b, c, d, in[12], S11, 0x6B901122L);
FF ( d, a, b, c, in[13], S12, 0xFD987193L);
FF ( c, d, a, b, in[14], S13, 0xA679438EL);
FF ( b, c, d, a, in[15], S14, 0x49B40821L);
#define S21 5
#define S22 9
#define S23 14
#define S24 20
GG ( a, b, c, d, in[ 1], S21, 0xF61E2562L);
GG ( d, a, b, c, in[ 6], S22, 0xC040B340L);
GG ( c, d, a, b, in[11], S23, 0x265E5A51L);
GG ( b, c, d, a, in[ 0], S24, 0xE9B6C7AAL);
GG ( a, b, c, d, in[ 5], S21, 0xD62F105DL);
GG ( d, a, b, c, in[10], S22, 0x02441453L);
GG ( c, d, a, b, in[15], S23, 0xD8A1E681L);
GG ( b, c, d, a, in[ 4], S24, 0xE7D3FBC8L);
GG ( a, b, c, d, in[ 9], S21, 0x21E1CDE6L);
GG ( d, a, b, c, in[14], S22, 0xC33707D6L);
GG ( c, d, a, b, in[ 3], S23, 0xF4D50D87L);
GG ( b, c, d, a, in[ 8], S24, 0x455A14EDL);
GG ( a, b, c, d, in[13], S21, 0xA9E3E905L);
GG ( d, a, b, c, in[ 2], S22, 0xFCEFA3F8L);
GG ( c, d, a, b, in[ 7], S23, 0x676F02D9L);
GG ( b, c, d, a, in[12], S24, 0x8D2A4C8AL);
#define S31 4
#define S32 11
#define S33 16
#define S34 23
HH ( a, b, c, d, in[ 5], S31, 0xFFFA3942L);
HH ( d, a, b, c, in[ 8], S32, 0x8771F681L);
HH ( c, d, a, b, in[11], S33, 0x6D9D6122L);
HH ( b, c, d, a, in[14], S34, 0xFDE5380CL);
HH ( a, b, c, d, in[ 1], S31, 0xA4BEEA44L);
HH ( d, a, b, c, in[ 4], S32, 0x4BDECFA9L);
HH ( c, d, a, b, in[ 7], S33, 0xF6BB4B60L);
HH ( b, c, d, a, in[10], S34, 0xBEBFBC70L);
HH ( a, b, c, d, in[13], S31, 0x289B7EC6L);
HH ( d, a, b, c, in[ 0], S32, 0xEAA127FAL);
HH ( c, d, a, b, in[ 3], S33, 0xD4EF3085L);
HH ( b, c, d, a, in[ 6], S34, 0x04881D05L);
HH ( a, b, c, d, in[ 9], S31, 0xD9D4D039L);
HH ( d, a, b, c, in[12], S32, 0xE6DB99E5L);
HH ( c, d, a, b, in[15], S33, 0x1FA27CF8L);
HH ( b, c, d, a, in[ 2], S34, 0xC4AC5665L);
#define S41 6
#define S42 10
#define S43 15
#define S44 21
10
II ( a, b, c, d, in[ 0], S41, 0xF4292244L);
II ( d, a, b, c, in[ 7], S42, 0x432AFF97L);
II ( c, d, a, b, in[14], S43, 0xAB9423A7L);
II ( b, c, d, a, in[ 5], S44, 0xFC93A039L);
II ( a, b, c, d, in[12], S41, 0x655B59C3L);
II ( d, a, b, c, in[ 3], S42, 0x8F0CCC92L);
II ( c, d, a, b, in[10], S43, 0xFFEFF47DL);
II ( b, c, d, a, in[ 1], S44, 0x85845DD1L);
II ( a, b, c, d, in[ 8], S41, 0x6FA87E4FL);
II ( d, a, b, c, in[15], S42, 0xFE2CE6E0L);
II ( c, d, a, b, in[ 6], S43, 0xA3014314L);
II ( b, c, d, a, in[13], S44, 0x4E0811A1L);
II ( a, b, c, d, in[ 4], S41, 0xF7537E82L);
II ( d, a, b, c, in[11], S42, 0xBD3AF235L);
II ( c, d, a, b, in[ 2], S43, 0x2AD7D2BBL);
II ( b, c, d, a, in[ 9], S44, 0xEB86D391L);
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}
return m1;
}
Программа 2
// pasoib_1_1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
using namespace std;
FILE *file;
unsigned char x1;
file=fopen(p, "rb+");
if ((size%2!=0)&&(i==size-1))
{
unsigned int e=0;
y2=unsigned char(e);
}
else
{
fread(&x1, sizeof(unsigned char),1,file);
y2=x1;
}
unsigned int y0 = (y1 << 8) | y2;
y = (y + y0)%65536;
if ((i==size-2)||(i==size-1))
{
out << y;
}
12
}
return 0;
}
Программа 3
// pasoib_1_2.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
using namespace std;
ofstream out("keys.txt");
ofstream out1("C:\\Users\\Настя\\Desktop\\Программы\\pasoib_1_3\\pasoib_1_3\\keys.txt");
ofstream out2("C:\\Users\\Настя\\Desktop\\Программы\\pasoib_1_4\\pasoib_1_4\\keys.txt");
int p, q, a;
int x, y;
if (x==0)
{
p=i;
13
goto metka1;
}
}
metka1:
///Нахождение числа q
for (int b=2; b<p; b++)
{
int u=0;
int y;
if ((p-1)%b==0)
{
y=(p-1)/b;
u=1;
}
if (u==1)
{
int x=0;
double i1=y;
if (x==0)
{
q=y;
goto metka2;
}
}
}
metka2:
///Нахождение числа a
for (int i=2; i<p-1; i++)
{
int b;
b=f0(q, i, p);
if (b==1)
{
a=i;
goto metka3;
}
}
metka3:
///Выбор числа x
srand(time(NULL));
14
x=1+rand()%(q-1);
///Вычисление числа y
y=f0(x, a, p);
return 0;
}
Программа 4
// pasoib_1_3.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
using namespace std;
ifstream in("C:\\Users\\Настя\\Desktop\\Программы\\pasoib_1_1\\pasoib_1_1\\hash.txt");
ifstream in1("keys.txt");
ofstream out("rs.txt");
ofstream out1("C:\\Users\\Настя\\Desktop\\Программы\\pasoib_1_4\\pasoib_1_4\\rs.txt");
int p, q, a;
int x, y;
int k;
int r, s;
int h;
15
///Выбор числа k
srand(time(NULL));
k=1+rand()%(q-1);
///Вычисление r
r=f0(k, a, p);
r=r%q;
///Вычисление s
int s0;
///Нахождение числа s0 = k^(-1) mod q (обобщенный алгоритм Евклида)
int u[3];
int v[3];
int t[3];
while (v[0]!=0)
{
int q0 = u[0]/v[0];
t[0]=u[0]%v[0];
t[1]=u[1]-q0*v[1];
t[2]=u[2]-q0*v[2];
s0=u[1];
while (s0<0)
s0=s0+q;
s=(s0*(h+x*r))%q;
return 0;
}
Программа 5
// pasoib_1_4.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
using namespace std;
ifstream in("C:\\Users\\Настя\\Desktop\\Программы\\pasoib_1_1\\pasoib_1_1\\hash.txt");
ifstream in1("keys.txt");
ifstream in2("rs.txt");
ofstream out("rez.txt");
int p, q, a;
int x, y;
int r, s;
int w;
int u1, u2, vv;
int h;
in >> h;
in1 >> p >> q >> a >> y;
in2 >> r >> s;
while (v[0]!=0)
{
int q0 = u[0]/v[0];
t[0]=u[0]%v[0];
t[1]=u[1]-q0*v[1];
t[2]=u[2]-q0*v[2];
w=u[1];
while (w<0)
w=w+q;
///Вычисление u1 и u2
u1=(h*w)%q;
u2=(r*w)%q;
///Вычисление v
int v1, v2;
v1=f0(u1, a, p);
v2=f0(u2, y, p);
vv=((v1*v2)%p)%q;
///Проверка подписи
if ((vv==r)&&(r>0)&&(r<q)&&(s>0)&&(s<q))
out << "Подпись действительна" << endl;
else out << "Подпись недействительна" << endl;
return 0;
}
5. Вывод
В процессе выполнения лабораторной работы мы познакомились с
общими принципами защиты программного обеспечения и способами
18
организации контроля целостности исполняемых модулей и важных
программных данных.
Механизм контроля целостности является важной компонентой
защиты, образуя отдельный функциональный уровень защиты информации
от НСД. Его принципиальным отличием от остальных механизмов защиты
является то, что данным механизмом может быть зарегистрирован сам факт
НСД, причем вне зависимости от причин его происхождения (например, в
результате использования злоумышленником ошибок и закладок в ПО).
Поэтому развитый набор механизмов контроля целостности является
важнейшим условием эффективной защиты от НСД.
19