(fileDlg. DoModal() == IDOK)
{_save = fileDlg. GetFileName(); // Запись имени файла_save = fileDlg. GetPathName(); // Запись полного имени файла
}
}
void CCoursworkDlg: OnBnClickedButtonKey() // выбор ключа для работы программы
{
TCHAR Filter[] = _T
(«TXT Filters (*.txt)|*.txt||»); //
фильтор для выбора формата файлов(_T(«C:\\»)); // выбор начальной директории
CFileDialog
fileDlg (TRUE, 0, 0, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, Filter); // Создание окна диолога
if (fileDlg. DoModal() == IDOK)
{_key = fileDlg. GetFileName(); // Запись имени файла_key = fileDlg. GetPathName(); // Запись полного имени файла
}
(); // вызов функции для чтения ключа
}
CCoursworkDlg: OpenTxtFile() // функция чтения ключа
{(skm, 0, size);count = 0; // кол-во символов в файле
fstream t (fullfilename_key); // считывание в массив(int q = 0; q < size; q++)
{>> skm[q];
}.close();
}
CCoursworkDlg: ReadTxtFile() // функция чтения из файла
{(skl, 0, size);count = 0; // кол-во символов в файлеf (fullfilename_open); // считывание в массив(int q = 0; q < size; q++)
{>> skl[q];
}.close();
}
CCoursworkDlg: WriteTxtFile() // не пригодилось
{
}
CCoursworkDlg: CloseTxtFile() // запись конечного результата преобразований
{fout (fullfilename_save); // создаём объект класса ofstream для записи и связываем его с файлом cppstudio.txt
for (int e = 0; e < size; e++)
{<< out[e]; // запись строки в файл
}.close(); // закрываем файл
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
CCoursworkDlg: OnBnClickedButtonShifr() // для шифрования
{((filename_save!= «») && (filename_open!= «») && (filename_key!= «»)) // для проверки заполнения полей
{();
}
{(L «Выберите все параметры!»);
}
}
CCoursworkDlg: OnBnClickedButtonDeshifr() // для дешифроваания
{
if ((filename_save!= «») && (filename_open!= «») && (filename_key!= «»)) // для проверки заполнения полей
{();
}
{(L «Выберите все параметры!»);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Таблицы и общие функции для шифрования и дешифрования
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define Nb 4 // Количество столбцов, содержащих состояние в AES. Это константа в AES. Значение = 4
#define xtime(x) ((x<<1) ^ (((x>>7) & 1) * 0x1b)) //Xtime - это макрос, который находит произведение{02} и аргумент для xtime по модулю{1b}Nr = 10; // Количество раундов.Nk = 4; // Число 32-битных слов в ключе.char RoundKey[240]; // Массив, в котором хранятся раундовые ключи.char Key[32]; // Ключевой вклад в Программу AESgetSBoxValue (int num) // таблица для замены при шифровании
{sbox[256] = {
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, // 0
xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, // 1
xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, // 2
x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, // 3
x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, // 4
x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, // 5
xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, // 6
x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, // 7
xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, // 8
x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, // 9
xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, //A
xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, //B
xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, //C
x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, //D
xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, //E
x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16}; //F
return sbox[num];
}
// Круглый массив постоянных слов, Rcon [i], содержит значения, заданные
// x для мощности (i-1), являющейся степенью x (x обозначается как {02}) в поле GF (28)
// Обратите внимание, что i начинается с 1, а не 0).
int Rcon[255] = {
x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39,
x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef,
xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b,
x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63,
xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
x61,
0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8,
0xcb};
int getSBoxInvert (int num) // массив для обратной замены
{rsbox[256] =
{0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb
x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e
x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25
x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92
x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84
x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06
xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b
x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73
x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e
x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b
xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4
x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f
x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef
xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61
x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d};rsbox[num];
}
CCoursworkDlg: KeyExpansion() // функция генерации раундовых ключей
{i,
j;char temp[4], k;
// Ключ первого раунда - это сам ключ
for (i = 0; i<Nk; i++)
{[i * 4] = Key [i * 4];[i * 4 + 1] = Key [i * 4 + 1];[i * 4 + 2] = Key [i * 4 + 2]; [i * 4 + 3] = Key [i * 4 + 3];
}(i < (Nb * (Nr + 1))) // Все остальные раундовые ключи находятся из предыдущих раундов.
{(j = 0; j<4; j++)
{[j] = RoundKey[(i - 1) * 4 + j];
}(i% Nk == 0)
{= temp[0];[0] = temp[1];[1] = temp[2];[2] = temp[3];[3] = k;[0] = getSBoxValue (temp[0]);[1] = getSBoxValue (temp[1]);[2] = getSBoxValue (temp[2]);[3] = getSBoxValue (temp[3]);[0] = temp[0] ^ Rcon [i / Nk];
}if (Nk > 6 && i% Nk == 4)
{[0] = getSBoxValue (temp[0]);[1] = getSBoxValue (temp[1]);[2] = getSBoxValue (temp[2]);[3] = getSBoxValue (temp[3]);
}[i * 4 + 0] = RoundKey[(i - Nk) * 4 + 0] ^ temp[0];[i * 4 + 1] = RoundKey[(i - Nk) * 4 + 1] ^ temp[1];[i * 4 + 2] = RoundKey[(i - Nk) * 4 + 2] ^ temp[2];[i * 4 + 3] = RoundKey[(i - Nk) * 4 + 3] ^ temp[3];++;
}
}
CCoursworkDlg: AddRoundKey (int round) // функция добавления ключей
{i, j;(i = 0; i<4; i++)
{(j = 0; j<4; j++)
{[j] [i] ^= RoundKey [round * Nb * 4 + i * Nb + j];
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
// ШИФРОВАНИЕ ДЛЯ 128 БИТНОГО КЛЮЧА
////////////////////////////////////////////////////////////////////////////////////////////////////////
CCoursworkDlg: DefiningInputParameters() // тело основной функции при шифровании
{i;
// Копирование ключа и простого текста
for (i = 0; i<Nk * 4; i++)
{[i] = skm[i];
in[i] = skl[i];
}
(); // Функцию генерации ключей надо вызывать до шифрования
(); // функция
шифрования файла по алгоритму AES
// Вывести зашифрованный текст.();
}
void CCoursworkDlg: SubBytes() // замена исходных данных в матрице на данные из заменной таблицы
{i, j;(i = 0; i<4; i++)
{(j = 0; j<4; j++)
{[i]
[j] = getSBoxValue (state[i] [j]);
}
}
}
CCoursworkDlg: ShiftRows() // сдвиг каждой строки влево на на определенное колличество байт
{char temp;
// Сдвиг первой строки на 1 столбц влево
temp =
state[1] [0];[1] [0] = state[1] [1];[1] [1] = state[1] [2];[1] [2] = state[1]
[3];[1] [3] = temp;
// Сдвиг 2 строки на 2 влево= state[2] [0];[2] [0] = state[2] [2];[2] [2] = temp;=
state[2] [1];[2] [1] = state[2] [3];[2] [3] = temp;
// Сдвиг 3 строки на 3 влево= state[3] [0];
state[3] [0] = state[3] [3];[3] [3] = state[3] [2];[3] [2] = state[3] [1];[3] [1] = temp;
}
// ^ побитовое ИЛИCCoursworkDlg: MixColumns() // Функция смешивания столбцов
{i;char Tmp, Tm, t;(i = 0; i<4; i++)
{= state[0] [i];= state[0] [i] ^ state[1] [i] ^ state[2] [i] ^ state[3] [i];= state[0] [i] ^ state[1] [i]; Tm = xtime(Tm); state[0] [i] ^= Tm ^ Tmp;= state[1] [i] ^ state[2] [i]; Tm = xtime(Tm); state[1] [i] ^= Tm ^ Tmp;= state[2] [i] ^ state[3] [i]; Tm = xtime(Tm); state[2] [i] ^= Tm ^ Tmp;= state[3] [i] ^ t; Tm = xtime(Tm); state[3] [i] ^= Tm ^ Tmp;
}
}
void CCoursworkDlg: Cipher() // основная функция шифрования
{i, j, round = 0;
(i = 0; i<4; i++) // перенос входных данных в массив для обработки
{(j = 0; j<4; j++)
{[j] [i] = in [i * 4 + j];
}
}
// Добавьте ключ первого раунда в состояние перед началом раундов
AddRoundKey(0);
(round = 1; round<Nr; round++) // цикл для выполнения првых 9 раундов
{();();();(round);
}
// функции для последнего раунда:
SubBytes();
ShiftRows();
AddRoundKey(Nr);
(i = 0; i<4; i++) // копирование результатта в массив для вывода результата
{(j = 0; j<4; j++)
{[i * 4 + j] = state[j] [i];
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
// ДЕШИФРОВАНИЕ ДЛЯ 128 БИТНОГО КЛЮЧА
////////////////////////////////////////////////////////////////////////////////////////////////////////
CCoursworkDlg: Description()
{
// Копирование ключа и CipherText(int i = 0; i < Nk * 4; i++)
{[i] = skm[i];[i] = skl[i];
}
// Процедуру Key-Expansion необходимо вызывать перед процедурой дешифрования.
KeyExpansion();
// Следующий вызов функции расшифровывает CipherText с помощью ключа, используя алгоритм AES.();
();
}
InvSubBytes() // функция обратной замены
{i, j;(i = 0; i<4; i++)
{(j = 0; j<4; j++)
{[i]
[j] = getSBoxInvert (state[i] [j]);
}
}
}
InvShiftRows() // функция сдвига строк в право
{char temp;
// Поворот первой строки 1 столбца вправо
temp =
state[1] [3];[1] [3] = state[1] [2];[1] [2] = state[1] [1];[1] [1] = state[1]
[0];[1] [0] = temp;
// Второй= state[2] [0];[2] [0] = state[2] [2];[2] [2] = temp;=
state[2] [1];[2] [1] = state[2] [3];[2] [3] = temp;
// третьей= state[3] [0];[3] [0] = state[3] [1];[3] [1] = state[3] [2];[3] [2] = state[3] [3];[3] [3] = temp;
}
// Multiplty - это макрос, используемый для умножения чисел в поле GF (2 ^ 8)
#define
Multiply (x, y) (((y & 1) * x) ^ ((y>>1 & 1) * xtime(x)) ^
((y>>2 & 1) * xtime (xtime(x))) ^ ((y>>3 & 1) * xtime
(xtime(xtime(x)))) ^ ((y>>4 & 1) * xtime (xtime(xtime (xtime(x))))))
void InvMixColumns() // функция для обратного смешифания столбцов
{i;char a, b, c, d;(i = 0; i<4; i++)
{
= state[0] [i];= state[1] [i];= state[2] [i];= state[3] [i];
[0] [i] = Multiply (a, 0x0e) ^ Multiply (b, 0x0b) ^ Multiply (c, 0x0d) ^ Multiply (d, 0x09);[1] [i] = Multiply (a, 0x09) ^ Multiply (b, 0x0e) ^ Multiply (c, 0x0b) ^ Multiply (d, 0x0d);[2] [i] = Multiply (a, 0x0d) ^ Multiply (b, 0x09) ^ Multiply (c, 0x0e) ^ Multiply (d, 0x0b);[3] [i] = Multiply (a, 0x0b) ^ Multiply (b, 0x0d) ^ Multiply (c, 0x09) ^ Multiply (d, 0x0e);
}
}
// InvCipher - основная функция дешифрования.CCoursworkDlg: InvCipher()
{i, j, round = 0;(i = 0; i<4; i++) // Копируем вход CipherText в массив состояний.
{(j = 0; j<4; j++)
{[j] [i] = in [i * 4 + j];
}
}(Nr); // добавление первого ключа(round = Nr - 1; round>0; round-)
{();();(round);();
}
// Функции для последнего раунда:
InvShiftRows();
InvSubBytes();(0);(i = 0; i<4; i++) // копирование в выходной массив
{(j = 0; j<4; j++)
{[i * 4 + j] = state[j] [i];
}
}
}