Реализация алгоритма шифрования по ГОСТ 28147-89 - C#

Узнай цену своей работы

Формулировка задачи:

Добрый день! Пытаюсь реализовать все тот же алгоритм шифрования ГОСТ-89. Уже целую неделю долблюсь, и никак не могу понять, в чем моя ошибка. Значит, вкратце о проекте: - В основе данного алгоритма лежит основной шаг криптопреобразования. Он реализован в структуре

BasicSteep

:
Листинг программы
  1. using System;
  2. namespace Crypto
  3. {
  4. struct BasicStep
  5. {
  6. uint N1, N2, X;
  7. public BasicStep(ulong dateFragment, uint keyFragment)
  8. {
  9. N1 = (uint)(dateFragment >> 32); //Младшая часть файла
  10. N2 = (uint)((dateFragment << 32) >> 32); //Старшая часть файла
  11. X = keyFragment;
  12. }
  13. public ulong BasicEncrypt()
  14. {
  15. return (FourthAndFifthStep(ThirdStep(SecondStep(FirstStep()))));
  16. }
  17. //Сложение по модулю 2^32 младшей части с фрагментом ключа
  18. private uint FirstStep()
  19. {
  20. return (uint)((X + N1) % (Convert.ToUInt64(Math.Pow(2, 32))));
  21. }
  22. //Использование таблицы замены
  23. private uint SecondStep(uint S)
  24. {
  25. uint newS, S0, S1, S2, S3, S4, S5, S6, S7;
  26. //Разбиваем младшую часть файла на 8 4-х битовых чисел
  27. S0 = S >> 28;
  28. S1 = (S << 4) >> 28;
  29. S2 = (S << 8) >> 28;
  30. S3 = (S << 12) >> 28;
  31. S4 = (S << 16) >> 28;
  32. S5 = (S << 20) >> 28;
  33. S6 = (S << 24) >> 28;
  34. S7 = (S << 28) >> 28;
  35. //Производим замену по таблице замен
  36. S0 = ReplacementTab.Table0[S0];
  37. S1 = ReplacementTab.Table0[0x10 + S1];
  38. S2 = ReplacementTab.Table0[0x20 + S2];
  39. S3 = ReplacementTab.Table0[0x30 + S3];
  40. S4 = ReplacementTab.Table0[0x40 + S4];
  41. S5 = ReplacementTab.Table0[0x50 + S5];
  42. S6 = ReplacementTab.Table0[0x60 + S6];
  43. S7 = ReplacementTab.Table0[0x70 + S7];
  44. //Склеиваем 4-х битовые числа в одно 32-х битовое
  45. newS = S7 + (S6 << 4) + (S5 << 8) + (S4 << 12) + (S3 << 16) +
  46. (S2 << 20) + (S1 << 24) + (S0 << 28);
  47. return newS;
  48. }
  49. //Циклический сдвиг на 11 бит влево
  50. private uint ThirdStep(uint S)
  51. {
  52. return (uint) (S << 11) | (S >> 21);
  53. }
  54. private ulong FourthAndFifthStep(uint S)
  55. {
  56. ulong N;
  57. S = (N2 ^ S); //Сложение по модулю 2 старшего фрагмента данных с полученным из....
  58. //... ThirdStep() числом
  59. //Сдвиг по цепочке
  60. N2 = N1;
  61. N1 = S;
  62. //Склеиваем младший и старший фрагмент в один 64-х битовый блок данных
  63. N = ((ulong)N2) | (((ulong)N1) << 32);
  64. return N;
  65. }
  66. }
  67. }
Механизм зашифровки 32-З реализован в классе

E32

:
Листинг программы
  1. using System;
  2. namespace Crypto
  3. {
  4. class E32
  5. {
  6. static E32 e32 = null;
  7. byte[] byteFile, byteKey, encrByteFile;
  8. uint[] uintKey;
  9. ulong[] ulongFile, ulNewFile;
  10. private E32() { }
  11. private E32(byte[] file, byte[] key)
  12. {
  13. byteFile = file;
  14. byteKey = key;
  15. //Создание массива из 32-х битовых фрагментов ключа
  16. DatePartition part = new DatePartition(byteKey, DatePartition.FileType.Key);
  17. uintKey = part.GetKey;
  18. //Создание массива из 64-х битовых фрагментов данных
  19. part = new DatePartition(byteFile, DatePartition.FileType.File);
  20. ulongFile = part.GetFile;
  21. ulNewFile = ulongFile;
  22. //Получение зашифрованного фрагмента данных в виде байт-массива encrByteFile[]
  23. ConvertToByte(EncryptFile());
  24. }
  25. //Публичное свойство для получения зашифрованного байт-массива
  26. public byte[] GetEncryptFile
  27. {
  28. get { return encrByteFile; }
  29. }
  30. //Публичный метод для получения единственного экземпляра объекта класса
  31. public static E32 StartE32(byte[] file, byte[] key)
  32. {
  33. if (e32 == null)
  34. e32 = new E32(file, key);
  35. return e32;
  36. }
  37. //Непосредственная реализация 32-З (3 раза К0-К7 и 1 раз К7-К0)
  38. private ulong[] EncryptFile()
  39. {
  40. BasicStep[] K = new BasicStep[8];
  41. ulNewFile[0] = ulongFile[0];
  42. for (int j = 0; j < 3; j++)
  43. {
  44. for (int i = 0; i < K.Length; i++)
  45. {
  46. K[i] = new BasicStep(ulNewFile[0], uintKey[i]);
  47. ulNewFile[0] = K[i].BasicEncrypt();
  48. }
  49. }
  50. for (int i = K.Length - 1; i >= 0; i--)
  51. {
  52. K[i] = new BasicStep(ulNewFile[0], uintKey[i]);
  53. ulNewFile[0] = K[i].BasicEncrypt();
  54. }
  55. return ulNewFile;
  56. }
  57. //Метод для конвертации массива ulong в байт-массив
  58. private void ConvertToByte(ulong[] fl)
  59. {
  60. byte[] newFile = new byte[8];
  61. uint part1, part2;
  62. string str, str1, str2;
  63. string[] arrStr = new string[8];
  64. part1 = (uint)(fl[0] >> 32);
  65. part2 = (uint)((fl[0] << 32) >> 32);
  66. str1 = Convert.ToString(part1, 2);
  67. while (str1.Length < 32)
  68. str1 = "0" + str1;
  69. str2 = Convert.ToString(part2, 2);
  70. while (str2.Length < 32)
  71. str2 = "0" + str2;
  72. str = str1 + str2;
  73. int count = 0;
  74. for (int i = 0; i < str.Length; i++)
  75. {
  76. if ((i % 8 == 0) && (i != 0))
  77. count++;
  78. arrStr[count] += str[i];
  79. }
  80. for (int i = 0; i < arrStr.Length; i++)
  81. {
  82. newFile[i] = Convert.ToByte(arrStr[i], 2);
  83. }
  84. encrByteFile = newFile;
  85. }
  86. }
  87. }
Для расшифровки (32-Р) реализован аналогичный класс

D32

, отличается только порядком действий в методе DecryptFile() (1 раз К0-К7 и 3 раза К7-К0). Ошибка скорее всего заключена в самом алгоритме. Как я это понял: Если в методе EncryptFile() оставить только 2 строки
Листинг программы
  1. ulNewFile[0] = ulongFile[0];
  2. return ulNewFile;
при запуске шифрования на выходе получим исходный файл. Значит, все преобразования, помимо самого шифра работают корректно. Может, я что-то не так понял в самом алгоритме шифрования? Надеюсь на вашу помощь) З.Ы.: Весь проект в прикрепленном файле. В папке Debug есть два файла:

1.txt

- 8-ми байтовый текстовый файл для зашифровки и файл

key

- 256-битовый файл ключа.

Решение задачи: «Реализация алгоритма шифрования по ГОСТ 28147-89»

textual
Листинг программы
  1. using System;
  2.  
  3. namespace Crypto
  4. {
  5.     struct BasicStep
  6.     {
  7.         uint N1, N2, X;
  8.  
  9.         public BasicStep(ulong dateFragment, uint keyFragment)
  10.         {
  11.             N1 = (uint)(dateFragment >> 32);
  12.             N2 = (uint)((dateFragment << 32) >> 32);
  13.             X = keyFragment;
  14.         }
  15.  
  16.         public ulong BasicEncrypt(bool IsLastStep)
  17.         {
  18.             return (FourthAndFifthStep(IsLastStep, ThirdStep(SecondStep(FirstStep()))));
  19.         }
  20.  
  21.         private uint FirstStep()
  22.         {
  23.             return (uint)((X + N1) % (Convert.ToUInt64(Math.Pow(2, 32))));
  24.         }
  25.  
  26.         private uint SecondStep(uint S)
  27.         {
  28.             uint newS, S0, S1, S2, S3, S4, S5, S6, S7;
  29.  
  30.             S0 = S >> 28;
  31.             S1 = (S << 4) >> 28;
  32.             S2 = (S << 8) >> 28;
  33.             S3 = (S << 12) >> 28;
  34.             S4 = (S << 16) >> 28;
  35.             S5 = (S << 20) >> 28;
  36.             S6 = (S << 24) >> 28;
  37.             S7 = (S << 28) >> 28;
  38.  
  39.             S0 = ReplacementTab.Table0[S0];
  40.             S1 = ReplacementTab.Table0[0x10 + S1];
  41.             S2 = ReplacementTab.Table0[0x20 + S2];
  42.             S3 = ReplacementTab.Table0[0x30 + S3];
  43.             S4 = ReplacementTab.Table0[0x40 + S4];
  44.             S5 = ReplacementTab.Table0[0x50 + S5];
  45.             S6 = ReplacementTab.Table0[0x60 + S6];
  46.             S7 = ReplacementTab.Table0[0x70 + S7];
  47.  
  48.             newS = S7 + (S6 << 4) + (S5 << 8) + (S4 << 12) + (S3 << 16) +
  49.                     (S2 << 20) + (S1 << 24) + (S0 << 28);
  50.  
  51.             return newS;
  52.         }
  53.  
  54.         private uint ThirdStep(uint S)
  55.         {
  56.             return (uint)(S << 11) | (S >> 21);
  57.         }
  58.  
  59.         //Теперь принимает в качестве параметра IsLastStep
  60.         private ulong FourthAndFifthStep(bool IsLastStep, uint S)
  61.         {
  62.             ulong N;
  63.  
  64.             S = (S ^ N2);
  65.  
  66.             //Если шаг последний - сдвиг по цепочке не производится
  67.             if (!IsLastStep)
  68.             {
  69.                 N2 = N1;
  70.                 N1 = S;
  71.             }
  72.             else
  73.                 N2 = S;
  74.  
  75.             N = ((ulong)N2) | (((ulong)N1) << 32);
  76.  
  77.             return N;
  78.         }
  79.     }
  80. }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

7   голосов , оценка 3.714 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы