
Новичок
Профиль
Группа: Участник
Сообщений: 3
Регистрация: 23.4.2011
Репутация: нет Всего: нет
|
Задание к лабораторной: шифровать и дешифровать файл по алгоритму ГОСТ 28147-89 в режиме шифрования CBC. Всё выполнил как описано в алгоритме, но результат дешифрования отличается от исходного файла. Уже месяц сижу над этим проектом. Не могу найти ошибку. | Код | private void Encode_Click(object sender, EventArgs e) { FileStream fs = File.OpenRead(filenameOpen); //Открываем файл для чтения int len = (int)fs.Length; //Файл представляется в виде массива байт, определим размерность этого массива byte[] Byte = new byte[len]; fs.Read(Byte, 0, len); //Считали файл в виде массива байт fs.Close(); UInt32[] Text32 = Bit32(Byte); UInt32[] Key32 = Ключ(KeyText1.Text); UInt32 b = 0; for (int j = 0; j < Text32.Length / 2; j++) { for (int i = 0; i < 32; i++) { b = Text32[2 * j + 1]; Text32[2 * j + 1] = Text32[2 * j + 1] + Key32[Index(i, 24)]; Text32[2 * j + 1] = Подстановка(Bit4(Text32[2 * j + 1])); Text32[2 * j + 1] = Сдвиг(Text32[2 * j + 1], 11, true); Text32[2 * j + 1] = Text32[2 * j + 1] ^ Text32[2 * j]; Text32[2 * j] = b; } // Text32 = Режим(Text32, 2 * j); } FileStream file = File.OpenWrite(filenameSave); //Создаем файл для записи file.Write(ByteText(Text32), 0, len); file.Close(); }
private void Decode_Click(object sender, EventArgs e) { FileStream fs = File.OpenRead(filenameOpen); //Открываем файл для чтения int len = (int)fs.Length; //Файл представляется в виде массива байт, определим размерность этого массива byte[] Byte = new byte[len]; fs.Read(Byte, 0, len); //Считали файл в виде массива байт fs.Close(); UInt32[] Text32 = Bit32(Byte); UInt32[] Key32 = Ключ(KeyText1.Text); UInt32 b = 0; for (int j = 0; j < Text32.Length / 2; j++) { for (int i = 0; i < 32; i++) { b = Text32[2 * j + 1]; Text32[2 * j + 1] = Text32[2 * j + 1] + Key32[Index(i, 8)]; Text32[2 * j + 1] = Подстановка(Bit4(Text32[2 * j + 1])); Text32[2 * j + 1] = Сдвиг(Text32[2 * j + 1], 11, true); Text32[2 * j + 1] = Text32[2 * j + 1] ^ Text32[2 * j]; Text32[2 * j] = b; } // Text32 = Режим(Text32, 2 * j); } FileStream file = File.OpenWrite(filenameSave); //Создаем файл для записи file.Write(ByteText(Text32), 0, len); file.Close(); }
public static byte[,] EcTable = new byte[8, 16] { {4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3}, {14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9}, {5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11}, {7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3}, {6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2}, {4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14}, {13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12}, {1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12} };
public static UInt32[] Bit32(byte[] b) { int n = b.Length; if ((n % 4) != 0) n = n + (4 - (n % 4)); UInt32[] a = new UInt32[n / 4]; for (int i = 0; i < n / 4; i++) { if ((i % (b.Length / 4) != 0) | (i == 0)) a[i] = ((((UInt32)b[4 * i] << 8) | (UInt32)b[4 * i + 1]) << 8 | (UInt32)b[4 * i + 2]) << 8 | (UInt32)b[4 * i + 3]; else { switch (n % b.Length) { case 0: break; case 1: a[i] = (((((UInt32)b[4 * i] << 8) | (UInt32)b[4 * i + 1]) << 8) | (UInt32)b[4 * i + 2]) << 8; break; case 2: a[i] = (((UInt32)b[4 * i] << 8) | (UInt32)b[4 * i + 1]) << 16; break; case 3: a[i] = (UInt32)b[4 * i] << 24; break; } } } return a; }
public static UInt32[] Ключ(string str) { if (str.Length < 32) //Если ключ пользователя менее 256 бит for (int j = str.Length; j < 32; j++) //то увеличиваем до 256 str += (char)(j+1040); //добавляя символы кириллицы else str = str.Substring(0, 32); //иначе вырезаем строку размером 32 символов byte[] a = new byte[str.Length]; for (int i = 0; i < str.Length; i++) { a[i] = (byte)str[i]; } UInt32[] bit = Bit32(a); return bit; } //Циклический сдвиг, c = true - влево; false - вправо. Для 32-битных чисел public static UInt32 Сдвиг(UInt32 a, int b, bool c) { UInt32 n = a; if (c) a = (a << b) | (n >> (32 - b)); else a = (a >> b) | (n << (32 - b)); return a; } //Разбиваем текст на 4-битные куски public static UInt32[] Bit4(UInt32 a) { UInt32[] n = new UInt32[8]; for (int i = 0, j = 0; i < 8; i++, j++) { n[i] = 0x0000000f & (a >> 4 * j); } return n; } //Индекс массива ключа public static int Index(int n, int b) { if (n < b) n = n % 8; else n = 7 - (n % 8); return n; } //Табличная подстановка public static UInt32 Подстановка(UInt32[] n) { UInt32 a = 0; for (int i = 0; i < 8; i++) n[i] = EcTable[i, n[i]]; for (int i = 7; i > -1; --i) a = (a << 4) | n[i]; return a; } //Режим шифрования CBC public static UInt32[] Режим(UInt32[] a, int n) { if (n != 0) { a[n] = a[n - 2] ^ a[n]; a[n + 1] = a[n - 1] ^ a[n + 1]; } else { a[n] = 0x44DC86A1 ^ a[n]; a[n + 1] = 0x84C3ECB9 ^ a[n + 1]; } return a; } //Конвертируем массив UInt32 в массив byte, чтобы записать фаил public static byte[] ByteText(UInt32[] a) { byte[] bit = new byte[a.Length * 4]; for (int i = 0; i < a.Length; i++) { bit[4 * i + 3] = (byte)a[i]; bit[4 * i + 2] = (byte)(a[i] >> 8); bit[4 * i + 1] = (byte)(a[i] >> 16); bit[4 * i] = (byte)(a[i] >> 24); } return bit; }
|
Присоединённый файл ( Кол-во скачиваний: 14 )
Form1.cs 9,34 Kb
|