- •2012 Содержание
- •Задание на выполнение курсового проекта
- •1 Краткие сведения о стандарте шифрованияDes
- •2. Режим des-ecb.
- •2.1. Общая схема шифрования.
- •2.2. Исходный текст класса шифрования.
- •2.3. Пример шифрования и расшифрования
- •3. Режим des-cbc
- •3.1. Общая схема шифрования
- •3.2. Исходный текст процедуры шифрования и дешифрования
- •3.3. Пример шифрования и расшифрования
- •4. Режим тройной des
- •4.1. Общие схемы шифрования
- •4.2. Исходные тексты процедур шифрования и дешифрования
- •4.3. Пример шифрования и дешифрования методомTripleDesede3
- •5. Руководство пользователя программы
- •5.5.2 Использование программного средства
- •Класс TestWindow
2.2. Исходный текст класса шифрования.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DESCryptography_Shvedov_Dm_A
{
public class Class_DES_SDmA
{
public BitArray[] Bloks;
public BitArray StartKey64 = new BitArray(64);
public BitArray StartVector = new BitArray(64);
public byte[] FirstKey = new byte[1];
public byte[] SecondKey = new byte[1];
public byte[] ThirdKey = new byte[1];
public bool CBCFlag = false;
public List<string> Mas = new List<string>();
//**********************************************
public Class_DES_SDmA()
{
Bloks = new BitArray[1];
}
public Class_DES_SDmA(int BloksCount, int LengthBits)
{
Bloks = new BitArray[BloksCount];
for (int i = 0; i < Bloks.Length; i++)
{
Bloks[i] = new BitArray(LengthBits);
}
}
// Инициализация класса. Формируем блоки информации. Добавляем незначащие нули справа при необходимости
public Class_DES_SDmA(byte[] bytes)
{
bool check = false;
// Инициализируем массив нужного размера, кратный 8 байтам (64 битам)
if (Math.IEEERemainder(bytes.Length, 8) != 0.0)
{
int Count = ((int)(Math.Truncate((decimal)(bytes.Length / 8))) + 1);
Bloks = new BitArray[Count];
check = true;
}
else
{
int h = (int)(bytes.Length / 8);
Bloks = new BitArray[h];
check = false;
}
byte[] buf = new byte[8];
for (int i = 0; i < Bloks.Length; i++)
{
if (i == Bloks.Length - 1)
{
if (check)
{
// необходимо справа добавить незначащие нулевые биты
int NumFulBytes = bytes.Length - i * 8;
for (int j = 0; j < NumFulBytes; j++)
{
buf[j] = bytes[i * 8 + j];
}
for (int k = NumFulBytes; k < 8; k++)
{
// добавляем нули
byte B = 0;
buf[k] = B;
}
}
else
{
for (int j = 0; j < 8; j++)
{ buf[j] = bytes[i*8 + j]; }
}
}
else
{
for (int j = 0; j < 8; j++)
{ buf[j] = bytes[i*8 + j]; }
}
Bloks[i] = new BitArray(buf);
PrintBitArray(Bloks[i], 8, " ", "Исходный блок бит... Блок № " + i.ToString());
// Добавляем переворачивание битов
Bloks[i] = RebuildBits(Bloks[i]);
PrintBitArray(Bloks[i], 8, " ", "Перевернутые биты в блоке...");
}
}
//**********************************************
public BitArray Chetnost(BitArray b)
{
BitArray B = new BitArray(64);
BitArray x = new BitArray(1);
BitArray xnow = new BitArray(1);
int k = 0;
for (int i = 0; i < 64; i++)
{
if (Math.IEEERemainder(i + 1, 8) == 0)
{
B[i] = x[0];
k++;
x[0] = false;
}
else
{
B[i] = b[i - k];
xnow[0] = b[i - k];
x = x.Xor(xnow);
}
}
return B;
}
public BitArray RebuildBits(BitArray b)
{
BitArray B = new BitArray(b.Length);
for (int i = 0; i < Math.Floor((double)(b.Length / 8)); i++)
{
for (int j = 0; j < 4; j++)
{
B[i * 8 + j] = b[(i + 1) * 8 - j - 1];
B[(i + 1) * 8 - j - 1] = b[i * 8 + j];
}
}
return B;
}
// Формирует из массива строку из 0 и 1 для вывода на экран
public void PrintBitArray(BitArray B, int step, string s, string message)
{
string str = " ";
if (B != null)
{
Mas.Add(message + ":");
for (int i = 0; i < B.Length; i++)
{
if (B[i] == true) { str += "1"; }
else { str += "0"; }
if (Math.IEEERemainder(i + 1, step) == 0.0) { str += s; }
}
}
else
{
Mas.Add("");
Mas.Add("");
str = s + message + s;
}
Mas.Add(str);
}
// Устанавливаем ключ шифрования
public void SetKey(byte[] bytekey)
{
BitArray newb = new BitArray(bytekey);
newb = new BitArray(RebuildBits(newb));
PrintBitArray(newb, 7, "__", "Ключ из 56 бит");
newb = new BitArray(Chetnost(newb));
PrintBitArray(newb, 8, " ", "Ключ из 64 бита, после добавления бит четности");
StartKey64 = new BitArray(newb);
//PrintBitArray(StartKey64, 8, " ", "Стартовый 64 битный Ключ");
}
// Устанавливаем начальный вектор
public void SetVector(byte[] byteVector)
{
BitArray b = new BitArray(byteVector);
StartVector = new BitArray(RebuildBits(b));
//PrintBitArray(StartKey64, 8, " ", "Стартовый 64 вектор");
}
public void SetFirstKey(byte[] bytekey)
{
FirstKey = bytekey;
//PrintBitArray(StartKey64, 8, " ", "Стартовый 64 битный Ключ");
}
public void SetSecondKey(byte[] bytekey)
{
SecondKey = bytekey;
//PrintBitArray(StartKey64, 8, " ", "Стартовый 64 битный Ключ");
}
public void SetThirdKey(byte[] bytekey)
{
ThirdKey = bytekey;
//PrintBitArray(StartKey64, 8, " ", "Стартовый 64 битный Ключ");
}
// Возвращает часть массива (хорошо выбирает половинки массива)
public BitArray GetBits(BitArray B, int start, int end)
{
BitArray NewB = new BitArray(end - start);
for (int i = start; i < end; i++)
{
NewB[i - start] = B[i];
}
return NewB;
}
// Самая первая перестановка 64 бит сообщения
public BitArray FirstMixBlok(BitArray blok)
{
//PrintBitArray(blok, 8, " ","До начальной перестановки");
// Начальная перестановка IP
BitArray NewBlok = new BitArray(64);
int Step = 0;
for (int i = 58; i<65; i=i+2)
{
for (int j =0; j<8; j++)
{
NewBlok[Step*8+j] = blok[i-j*8-1];
}
Step++;
}
Step = 4;
for (int i = 57; i < 65; i = i + 2)
{
for (int j = 0; j < 8; j++)
{
NewBlok[Step * 8 + j] = blok[(i - j * 8) - 1];
}
Step++;
}
//PrintBitArray(NewBlok, 8, " ","После начальной перестановки");
return NewBlok;
}
// Перестановка в конце шифрования всего блока данных (64 бит)
public BitArray EndMixBlok(BitArray blok)
{
// Конечная перестановка IP
BitArray NewBlok = new BitArray(64);
int Step = 0;
for (int i = 40; i <= 64; i = i + 8)
{
for (int j = 0; j < 8; j++)
{
NewBlok[8*j+Step] = blok[i-j - 1];
}
Step+=2;
}
Step = 1;
for (int i = 8; i <= 32; i = i + 8)
{
for (int j = 0; j < 8; j++)
{
NewBlok[Step + 8*j] = blok[i - j - 1];
}
Step+=2;
}
//PrintBitArray(blok, 8, " ", "После конечной перестановки");
return NewBlok;
}
// склеивает два массива бит
public BitArray Glue(BitArray b1, BitArray b2)
{
//PrintBitArray(b1, 8, " ", "Первый склеиваемый блок");
//PrintBitArray(b2, 8, " ", "Второй склеиваемый блок");
// Склеивает два блока бит
BitArray B = new BitArray(b1.Length + b2.Length);
for (int i = 0; i < b1.Length; i++)
{
B[i] = b1[i];
}
for (int j = b1.Length; j < B.Length; j++)
{
B[j] = b2[j - b1.Length];
}
//PrintBitArray(B, 8, " ", "Склеили");
return B;
}
// Склеивает зашифрованные/расшифрованные блоки бит и переводит их в массив байт
public byte[] GlueAndToByte(BitArray[] Bits)
{
byte[] Result = new byte[Bits.Length*8];
for (int i = 0; i < Bits.Length; i++)
{
// опять переворачиваем биты в байтах...
PrintBitArray(Bits[i], 8, " ", "Результат блока бит до перевертывания(исправление недочета BitArray)... Блок № "+i.ToString());
Bits[i] = RebuildBits(Bits[i]);
PrintBitArray(Bits[i], 8, " ", "Результат блока бит после перевертывания...");
Bits[i].CopyTo(Result, i * 8);
}
return Result;
}
// переводит массив bool[] в int
public int BoolToInt(bool[] b)
{
int el = 0;
for (int i = 0; i < b.Length; i++)
{
if (b[i]) { el += (int)(Math.Pow((double)(2), (double)(b.Length - i - 1))); }
}
return el;
}
// Перестановка с помощью узлов замены
public BitArray MixUzelZameni(BitArray B)
{
BitArray Ret = new BitArray(0);
BitArray[] RB = new BitArray[16];
bool[] buf = { false, false, false, false };
RB[0] = new BitArray(buf);
bool[] buf1 = { false, false, false, true };
RB[1] = new BitArray(buf1);
bool[] buf2 = { false, false, true, false };
RB[2] = new BitArray(buf2);
bool[] buf3 = { false, false, true, true };
RB[3] = new BitArray(buf3);
bool[] buf4 = { false, true, false, false };
RB[4] = new BitArray(buf4);
bool[] buf5 = { false, true, false, true };
RB[5] = new BitArray(buf5);
bool[] buf6 = { false, true, true, false };
RB[6] = new BitArray(buf6);
bool[] buf7 = { false, true, true, true };
RB[7] = new BitArray(buf7);
bool[] buf8 = { true, false, false, false };
RB[8] = new BitArray(buf8);
bool[] buf9 = { true, false, false, true };
RB[9] = new BitArray(buf9);
bool[] buf10 = { true, false, true, false };
RB[10] = new BitArray(buf10);
bool[] buf11 = { true, false, true, true };
RB[11] = new BitArray(buf11);
bool[] buf12 = { true, true, false, false };
RB[12] = new BitArray(buf12);
bool[] buf13 = { true, true, false, true };
RB[13] = new BitArray(buf13);
bool[] buf14 = { true, true, true, false };
RB[14] = new BitArray(buf14);
bool[] buf15 = { true, true, true, true };
RB[15] = new BitArray(buf15);
// сам массив узлов замены
int[,] uzli = {
{14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7}, //0
{0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8}, //1
{4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0}, //2
{15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13},
{15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10}, //4
{3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5},
{0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15}, //6
{13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9},
{10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8}, //8
{13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1},
{13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7}, //10
{1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12},
{7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15}, //12
{13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9},
{10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4}, //14
{3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14}, //15
{2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9},
{14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6}, //17
{4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14},
{11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3}, //19
{12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11},
{10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8}, //21
{9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6},
{4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13}, //23
{4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1},
{13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6}, //25
{1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2},
{6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12}, //27
{13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7},
{1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2}, //29
{7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8},
{2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11} //31
};
int uzel = 0;
bool[] Num = new bool[1];
bool[] Num1 = new bool[1];
for (int i = 0; i < 8; i++)
{
Num = new bool[2];
Num[0] = B[6*i];
Num[1] = B[6*i+5];
Num1 = new bool[4];
Num1[0] = B[6*i+1];
Num1[1] = B[6*i+2];
Num1[2] = B[6*i+3];
Num1[3] = B[6*i+4];
uzel = uzli[i * 4 + BoolToInt(Num), BoolToInt(Num1)];
Ret = Glue(Ret,RB[uzel]);
}
return Ret;
}
// перестановка в конце функции
public BitArray MixEndFunction(BitArray B)
{
BitArray NewB = new BitArray(32);
NewB[0] = B[16-1];
NewB[1] = B[7-1];
NewB[2] = B[20-1];
NewB[3] = B[21-1];
NewB[4] = B[29-1];
NewB[5] = B[12-1];
NewB[6] = B[28-1];
NewB[7] = B[17-1];
NewB[8] = B[1-1];
NewB[9] = B[15-1];
NewB[10] = B[23-1];
NewB[11] = B[26-1];
NewB[12] = B[5-1];
NewB[13] = B[18-1];
NewB[14] = B[31-1];
NewB[15] = B[10-1];
NewB[16] = B[2-1];
NewB[17] = B[8-1];
NewB[18] = B[24-1];
NewB[19] = B[14-1];
NewB[20] = B[32-1];
NewB[21] = B[27-1];
NewB[22] = B[3-1];
NewB[23] = B[9-1];
NewB[24] = B[19-1];
NewB[25] = B[13-1];
NewB[26] = B[30-1];
NewB[27] = B[6-1];
NewB[28] = B[22-1];
NewB[29] = B[11-1];
NewB[30] = B[4-1];
NewB[31] = B[25-1];
return NewB;
}
// перестановка в конце формирования ключа. из 56 получаем 48
public BitArray MixEndKeyCreate48(BitArray B)
{
BitArray NewB = new BitArray(48);
NewB[0] = B[14 - 1];
NewB[1] = B[17 - 1];
NewB[2] = B[11 - 1];
NewB[3] = B[24 - 1];
NewB[4] = B[1 - 1];
NewB[5] = B[5 - 1];
NewB[6] = B[3 - 1];
NewB[7] = B[28 - 1];
NewB[8] = B[15 - 1];
NewB[9] = B[6 - 1];
NewB[10] = B[21 - 1];
NewB[11] = B[10 - 1];
NewB[12] = B[23 - 1];
NewB[13] = B[19 - 1];
NewB[14] = B[12 - 1];
NewB[15] = B[4 - 1];
NewB[16] = B[26 - 1];
NewB[17] = B[8 - 1];
NewB[18] = B[16 - 1];
NewB[19] = B[7 - 1];
NewB[20] = B[27 - 1];
NewB[21] = B[20 - 1];
NewB[22] = B[13 - 1];
NewB[23] = B[2 - 1];
NewB[24] = B[41 - 1];
NewB[25] = B[52 - 1];
NewB[26] = B[31 - 1];
NewB[27] = B[37 - 1];
NewB[28] = B[47 - 1];
NewB[29] = B[55 - 1];
NewB[30] = B[30 - 1];
NewB[31] = B[40 - 1];
NewB[32] = B[51 -1];
NewB[33] = B[45 -1];
NewB[34] = B[33 -1];
NewB[35] = B[48 -1];
NewB[36] = B[44 -1];
NewB[37] = B[49 -1];
NewB[38] = B[39 -1];
NewB[39] = B[56 -1];
NewB[40] = B[34 -1];
NewB[41] = B[53 -1];
NewB[42] = B[46 -1];
NewB[43] = B[42 -1];
NewB[44] = B[50 -1];
NewB[45] = B[36 -1];
NewB[46] = B[29 -1];
NewB[47] = B[32 -1];
return NewB;
}
// Сдвиг 28 битной половинки. Итерации от 1 до 16
public BitArray SdvigKey28(BitArray OldB, int iterac)
{
BitArray NewB = new BitArray(28);
int Smechenie = 0;
switch (iterac)
{
case 1: Smechenie = 1; break; // 1
case 2: Smechenie = 2; break; // 1
case 3: Smechenie = 4; break; // 2
case 4: Smechenie = 6; break;
case 5: Smechenie = 8; break;
case 6: Smechenie = 10; break;
case 7: Smechenie = 12; break;
case 8: Smechenie = 14; break;
case 9: Smechenie = 15; break; // 1
case 10: Smechenie = 17; break; // 2
case 11: Smechenie = 19; break;
case 12: Smechenie = 21; break;
case 13: Smechenie = 23; break;
case 14: Smechenie = 25; break;
case 15: Smechenie = 27; break;
case 16: Smechenie = 28; break; // 1
}
for (int i = 0; i < OldB.Length; i++)
{
if (i - Smechenie < 0) { NewB[OldB.Length + i - Smechenie] = OldB[i]; }
else { NewB[i - Smechenie] = OldB[i]; }
}
return (NewB);
}
// Производит выборку бит из 64 битного ключа. Результат - 56 битный "ключ"
public BitArray KeyGen56(BitArray StartKey)
{
//PrintBitArray(StartKey, 8, " ", "Начальный ключ (64)");
BitArray Key56 = new BitArray(56);
int NumNow = 57;
for (int i = 1; i <= 56; i++)
{
Key56[i - 1] = StartKey[NumNow - 1];
NumNow -= 8;
if (i == 8) { NumNow = 58; }
if (i == 16) { NumNow = 59; }
if (i == 24) { NumNow = 60; }
if (i == 28) { NumNow = 63; }
if (i == 36) { NumNow = 62; }
if (i == 44) { NumNow = 61; }
if (i == 52) { NumNow = 28; }
}
return Key56;
}
// функция модификации HPart
public BitArray Function(BitArray L, BitArray K)
{
PrintBitArray(L, 8, " ", "LPart, Началась функция модификации f");
//PrintBitArray(K, 8, " ", "Key");
// функция шифрования
BitArray L_Out = new BitArray(32);
BitArray Tetrad = new BitArray(48);
// перестановка в начале функции
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 4; j++)
{
Tetrad[6 * i + 1 + j] = L[i * 4 + j];
}
if (i == 7) { Tetrad[6 * i + 5] = L[0]; }
else { Tetrad[6 * i + 5] = L[(i+1) * 4]; }
if (i == 0) { Tetrad[0] = L[L.Length-1]; }
else { Tetrad[6 * i] = L[(i - 1) * 4 + 3]; }
}
// перевели 32 битную в 48 битную последовательность
PrintBitArray(Tetrad, 8, " ", "Перевели 32 в 48. результат функции расширения Е");
// складываем по модулю 2
Tetrad = Tetrad.Xor(K);
PrintBitArray(Tetrad, 8, " ", "Xor. побитово суммируем по модулю 2");
// преобразуем 48 в 32
L_Out = new BitArray(MixUzelZameni(Tetrad));
PrintBitArray(L_Out, 8, " ", "Преобразовали 48 в 32. С помощью узлов замены");
// перестановка бит в конце функции
L_Out = new BitArray(MixEndFunction(L_Out));
PrintBitArray(L_Out, 8, " ", "Перестановка бит в конце функции. Перестановка P");
return L_Out;
}
// ШИФРОВАНИЕ
public BitArray[] CRYPT()
{
PrintBitArray(null, 0, "**********************", "ШИФРОВАНИЕ");
BitArray[] CodedBloks = new BitArray[Bloks.Length];
BitArray HPart = new BitArray(32);
BitArray LPart = new BitArray(32);
BitArray Key = new BitArray(56);
for (int NUMBlok = 0; NUMBlok< Bloks.Length; NUMBlok++)
{
BitArray NowBlok = new BitArray(Bloks[NUMBlok]);
PrintBitArray(NowBlok, 8, " ", "Исходное сообщение");
if (CBCFlag)
{
if (NUMBlok == 0)
{
// XOR with начальный вектор
PrintBitArray(StartVector, 8, " ", "Начальный вектор");
NowBlok = NowBlok.Xor(StartVector);
PrintBitArray(NowBlok, 8, " ", "Исходное сообщение XOR начальный вектор");
}
else
{
// XOR with предыдущий блок
NowBlok = NowBlok.Xor(CodedBloks[NUMBlok-1]);
PrintBitArray(NowBlok, 8, " ", "Исходное сообщение XOR предыдущий блок");
}
}
CodedBloks[NUMBlok] = FirstMixBlok(NowBlok);
PrintBitArray(CodedBloks[NUMBlok], 8, " ", "Начальная перестановка IP");
HPart = new BitArray(GetBits(CodedBloks[NUMBlok],0,32));
LPart = new BitArray(GetBits(CodedBloks[NUMBlok],32,64));
PrintBitArray(HPart, 8, " ", "HPart");
PrintBitArray(LPart, 8, " ", "LPart");
PrintBitArray(StartKey64, 8, " ", "Ключ 64 бита. С битами четности");
Key = KeyGen56(StartKey64);
PrintBitArray(Key, 8, " ", "ключ (56). Перестановка РС1");
BitArray Key28C = new BitArray(GetBits(Key, 0, 28));
BitArray Key28D = new BitArray(GetBits(Key, 28, 56));
PrintBitArray(Key28C, 4, " ", "ключ (28C (Left))");
PrintBitArray(Key28D, 4, " ", "ключ (28D (Right))");
for (int raund = 1; raund <= 16; raund++)
{
PrintBitArray(null, 0, "-----------------", "Итерация №"+raund.ToString());
// Циклический сдвиг половинок, их склеивание. Получаем очередной 48битный ключ
BitArray Key56 = new BitArray(Glue(SdvigKey28(Key28C, raund), SdvigKey28(Key28D, raund)));
PrintBitArray(Key56, 28, " ", "Ключ из 56 бит после циклического сдвига, итерация "+raund.ToString());
// Перемешиваем и производим выборку в конце создания ключа для данной итерации
BitArray Key48 = new BitArray(MixEndKeyCreate48(Key56));
PrintBitArray(Key48, 8, " ", "Ключ из 48 бит. Перестановка РС2");
// Модифицируем HPart
HPart = HPart.Xor(Function(LPart,Key48));
PrintBitArray(HPart, 8, " ", "HPart после модификации. HPart XOR f(LPart,Key)");
// Обмен половинок
if (raund != 16)
{
BitArray Buf = new BitArray(HPart);
HPart = new BitArray(LPart);
LPart = new BitArray(Buf);
PrintBitArray(HPart, 8, " ", "После обмена HPart");
PrintBitArray(LPart, 8, " ", "После обмена LPart");
}
}
// Склеивание половнок и Конечная перестановка
CodedBloks[NUMBlok] = EndMixBlok(Glue(HPart,LPart));
// шифрование блока окончено
PrintBitArray(CodedBloks[NUMBlok], 8, " ", "Результат шифрования блока. Конечная перестановка IP-1");
}
return (CodedBloks);
}
// ДеШИФРОВАНИЕ
public BitArray[] DeCRYPT()
{
PrintBitArray(null, 0, "**********************", "ДеШИФРОВАНИЕ");
BitArray[] CodedBloks = new BitArray[Bloks.Length];
BitArray HPart = new BitArray(32);
BitArray LPart = new BitArray(32);
BitArray Key = new BitArray(56);
for (int NUMBlok = 0; NUMBlok < Bloks.Length; NUMBlok++)
{
CodedBloks[NUMBlok] = FirstMixBlok(Bloks[NUMBlok]);
PrintBitArray(CodedBloks[NUMBlok], 8, " ", "Начальная перестановка IP");
HPart = new BitArray(GetBits(CodedBloks[NUMBlok], 0, 32));
LPart = new BitArray(GetBits(CodedBloks[NUMBlok], 32, 64));
PrintBitArray(HPart, 8, " ", "HPart");
PrintBitArray(LPart, 8, " ", "LPart");
PrintBitArray(StartKey64, 8, " ", "Ключ 64 бита. С битами четности");
Key = KeyGen56(StartKey64);
PrintBitArray(Key, 8, " ", "ключ (56). Перестановка РС1");
BitArray Key28C = new BitArray(GetBits(Key, 0, 28));
BitArray Key28D = new BitArray(GetBits(Key, 28, 56));
PrintBitArray(Key28C, 4, " ", "ключ (28C (Left))");
PrintBitArray(Key28D, 4, " ", "ключ (28D (Right))");
for (int raund = 16; raund >= 1; raund--)
{
PrintBitArray(null, 0, "-----------------", "Итерация №" + raund.ToString());
// Циклический сдвиг половинок, их склеивание. Получаем очередной 48битный ключ
BitArray Key56 = new BitArray(Glue(SdvigKey28(Key28C, raund), SdvigKey28(Key28D, raund)));
PrintBitArray(Key56, 28, " ", "Ключ из 56 бит после циклического сдвига, итерация " + raund.ToString());
// Перемешиваем и производим выборку в конце создания ключа для данной итерации
BitArray Key48 = new BitArray(MixEndKeyCreate48(Key56));
PrintBitArray(Key48, 8, " ", "Ключ из 48 бит. Перестановка РС2");
// Модифицируем HPart
HPart = HPart.Xor(Function(LPart, Key48));
PrintBitArray(HPart, 8, " ", "HPart после модификации. HPart XOR f(LPart,Key)");
// Обмен половинок
if (raund != 1)
{
BitArray Buf = new BitArray(HPart);
HPart = new BitArray(LPart);
LPart = new BitArray(Buf);
PrintBitArray(HPart, 8, " ", "После обмена HPart");
PrintBitArray(LPart, 8, " ", "После обмена LPart");
}
}
// Склеивание половнок и Конечная перестановка
CodedBloks[NUMBlok] = EndMixBlok(Glue(HPart, LPart));
// шифрование блока окончено
PrintBitArray(CodedBloks[NUMBlok], 8, " ", "Результат дешифрования блока. Конечная перестановка IP-1");
if (CBCFlag)
{ // выполняется для DES CBC
if (NUMBlok == 0)
{
// XOR with начальный вектор
CodedBloks[NUMBlok] = CodedBloks[NUMBlok].Xor(StartVector);
PrintBitArray(CodedBloks[NUMBlok], 8, " ", "Результат дешифрования XOR начальный вектор");
}
else
{
// XOR with предыдущий блок
CodedBloks[NUMBlok] = CodedBloks[NUMBlok].Xor(Bloks[NUMBlok-1]);
PrintBitArray(CodedBloks[NUMBlok], 8, " ", "Результат дешифрования XOR предыдущий шифрованный блок");
}
}
}
return (CodedBloks);
}
// Шифрование ECB
public byte[] CRYPT_ECB()
{
return GlueAndToByte(CRYPT());
}
// ДеШифрование ECB
public byte[] DeCRYPT_ECB()
{
return GlueAndToByte(DeCRYPT());
}
// Шифрование CBC
public byte[] CRYPT_CBC()
{
CBCFlag = true;
byte[] b = GlueAndToByte(CRYPT());
CBCFlag = false;
return b;
}
// ДеШифрование CBC
public byte[] DeCRYPT_CBC()
{
CBCFlag = true;
byte[] b = GlueAndToByte(DeCRYPT());
CBCFlag = false;
return b;
}
// ШИФРОВАНИЕ Triple DES EEE3
public byte[] CRYPT_EEE3()
{
BitArray[] CodedBloks = new BitArray[0];
SetKey(FirstKey);
CodedBloks = CRYPT();
SetKey(SecondKey);
Bloks = CodedBloks;
CodedBloks = CRYPT();
SetKey(ThirdKey);
Bloks = CodedBloks;
CodedBloks = CRYPT();
return GlueAndToByte(CodedBloks);
}
// ДеШИФРОВАНИЕ Triple DES EEE3
public byte[] DeCRYPT_EEE3()
{
BitArray[] CodedBloks = new BitArray[0];
SetKey(ThirdKey);
CodedBloks = DeCRYPT();
SetKey(SecondKey);
Bloks = CodedBloks;
CodedBloks = DeCRYPT();
SetKey(FirstKey);
Bloks = CodedBloks;
CodedBloks = DeCRYPT();
return GlueAndToByte(CodedBloks);
}
// ШИФРОВАНИЕ Triple DES EEE2
public byte[] CRYPT_EEE2()
{
BitArray[] CodedBloks = new BitArray[0];
SetKey(FirstKey);
CodedBloks = CRYPT();
SetKey(SecondKey);
Bloks = CodedBloks;
CodedBloks = CRYPT();
SetKey(FirstKey);
Bloks = CodedBloks;
CodedBloks = CRYPT();
return GlueAndToByte(CodedBloks);
}
// ДеШИФРОВАНИЕ Triple DES EEE2
public byte[] DeCRYPT_EEE2()
{
BitArray[] CodedBloks = new BitArray[0];
SetKey(FirstKey);
CodedBloks = DeCRYPT();
SetKey(SecondKey);
Bloks = CodedBloks;
CodedBloks = DeCRYPT();
SetKey(FirstKey);
Bloks = CodedBloks;
CodedBloks = DeCRYPT();
return GlueAndToByte(CodedBloks);
}
// ШИФРОВАНИЕ Triple DES EDE3
public byte[] CRYPT_EDE3()
{
BitArray[] CodedBloks = new BitArray[0];
SetKey(FirstKey);
CodedBloks = CRYPT();
SetKey(SecondKey);
Bloks = CodedBloks;
CodedBloks = DeCRYPT();
SetKey(ThirdKey);
Bloks = CodedBloks;
CodedBloks = CRYPT();
return GlueAndToByte(CodedBloks);
}
// ДеШИФРОВАНИЕ Triple DES EDE3
public byte[] DeCRYPT_EDE3()
{
BitArray[] CodedBloks = new BitArray[0];
SetKey(ThirdKey);
CodedBloks = DeCRYPT();
SetKey(SecondKey);
Bloks = CodedBloks;
CodedBloks = CRYPT();
SetKey(FirstKey);
Bloks = CodedBloks;
CodedBloks = DeCRYPT();
return GlueAndToByte(CodedBloks);
}
// ШИФРОВАНИЕ Triple DES EDE2
public byte[] CRYPT_EDE2()
{
BitArray[] CodedBloks = new BitArray[0];
SetKey(FirstKey);
CodedBloks = CRYPT();
SetKey(SecondKey);
Bloks = CodedBloks;
CodedBloks = DeCRYPT();
SetKey(FirstKey);
Bloks = CodedBloks;
CodedBloks = CRYPT();
return GlueAndToByte(CodedBloks);
}
// ДеШИФРОВАНИЕ Triple DES EDE2
public byte[] DeCRYPT_EDE2()
{
BitArray[] CodedBloks = new BitArray[0];
SetKey(FirstKey);
CodedBloks = DeCRYPT();
SetKey(SecondKey);
Bloks = CodedBloks;
CodedBloks = CRYPT();
SetKey(FirstKey);
Bloks = CodedBloks;
CodedBloks = DeCRYPT();
return GlueAndToByte(CodedBloks);
}
}
}