Алгоритм шифрования ГОСТ 28147-89. Режим простой замены - C#

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

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

Реализовывал алгоритм по wiki. Но что то не то получилось.Вот код:
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
namespace InformationSecurity1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        byte[,] Sblocks = {
                            {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}
                          };//Блок замен
        List<byte[]> lsKey = new List<byte[]>();//Список подключей размером в 4 байта
        List<byte[]> lsData = new List<byte[]>();//Список блоков открытого текста размером 8 байт
 
        byte[] fillingArrayData(List<byte[]> list)
        {
            byte[] array = new byte[list.Count * 8];
            int index = 0;
            for (int i = 0; i < list.Count; ++i)
            {
                for (int j = 0; j < list[i].Length; ++j)
                {
                    array[index] = list[i][j];
                    index++;
                }
            }
            return array;
        }
 
        void fillingListData(string data)
        {
            byte[] temp = Encoding.Default.GetBytes(data);
            int count = 0;
            byte[] k = new byte[8];
            for (int i = 0; i < temp.Length; ++i)
            {
                if (count != 8)
                {
                    k[count] = temp[i];
                    count++;
                }
                else
                {
                    lsData.Add(k);
                    --i;
                    count = 0;
                    k = new byte[8];
                }
            }
            lsData.Add(k);
        }
 
        void fillingListKey(string key)
        {
            byte[] temp = Encoding.Default.GetBytes(key);
            int count = 0;
            byte[] k = new byte[4];
            for (int i = 0; i < temp.Length; ++i)
            {
                if (count != 4)
                {
                    k[count] = temp[i];
                    count++;
                }
                else
                {
                    lsKey.Add(k);
                    --i;
                    count = 0;
                    k = new byte[4];
                }
            }
            lsKey.Add(k);
        }
 
        int lengthKey(string key)
        {
            byte[] temp = Encoding.Default.GetBytes(key);
            return temp.Length;
        }
 
        byte[] retL(byte[] data)
        {
            byte[] temp = new byte[4];
            for (int i = 0; i < 4; ++i)
            {
                temp[i] = data[i];
            }
            return temp;
        }//Возвращает старшую часть 8 байтового блока данных
 
        byte[] retR(byte[] data)
        {
            byte[] temp = new byte[4];
            int count = 4;
            for (int i = 0; i < 4; ++i)
            {
                temp[i] = data[count];
                count++;
            }
            return temp;
        }//Возвращает младшую часть 8 байтового блока данных

        byte[] mod2_32(byte[] a, byte[] b)
        {
            byte[] res;
            UInt32 A = BitConverter.ToUInt32(a, 0);
            UInt32 B = BitConverter.ToUInt32(b, 0);
            A += B;
            res = BitConverter.GetBytes(A);
            return res;
        }// Сложение по модулю 2^32
 
        UInt32 func(byte[] R, byte[] Ki)
        {
            byte[] s8 = new byte[8];
            int count = 0;
            byte[] s = mod2_32(R, Ki);
            for (int j = 0; j < s.Length; ++j)
            {
                byte e = (byte)((s[j] >> 4));
                s8[count] = e;
                ++count;
                byte f = (byte)((s[j] & 15));
                s8[count] = f;
                ++count;
            }
            for (int i = 0; i < 8; ++i)
            {
                    s8[i] = Sblocks[i, (int)s8[i]];
            }
            UInt32 result = BitConverter.ToUInt32(s8, 0);
            result = result << 11;
            return result;
        }
 
        byte[] encode(byte[] data)
        {
            byte[] L = retL(data);
            byte[] R = retR(data);
            byte[] block = new byte[4];
            UInt32 temp = 0;
            int index = 0;
            bool flag = true;
            for (int i = 0; i < 32; ++i)
            {
                if (i == 24)
                {
                    flag = false;
                }
                if (flag)
                {
                    if (index == 8)
                    {
                        index = 0;
                    }
                    temp = func(R, lsKey[index]);
                    index++;
                }
                else
                {
                    if (index == 8)
                    {
                        --index;
                    }
                    temp = func(R, lsKey[index]); 
                    --index;
                }
                temp = BitConverter.ToUInt32(L, 0) ^ temp;
                L = R;
                R = BitConverter.GetBytes(temp);
            }
            byte[] result = new byte[8];
            index = 0;
            for (int i = 0; i < 8; ++i)
            {
                if (i < 4)
                {
                    result[i] = L[i];
                }
                else
                {
                    result[i] = R[index];
                    index++;
                }
            }
            return result;
        }
 
        byte[] decode(byte[] data)
        {
            byte[] L = retL(data);
            byte[] R = retR(data);
            byte[] block = new byte[4];
            UInt64 temp = 0;
            int index = 0;
            bool flag = false;
            for (int i = 0; i < 32; ++i)
            {
                if (i == 24)
                {
                    flag = true;
                }
                if (flag)
                {
                    if (index == 8)
                    {
                        index = 0;
                    }
                    temp = func(R, lsKey[index]);
                    index++;
                }
                else
                {
                    if (index == 0)
                    {
                        index=7;
                    }
                    temp = func(R, lsKey[index]); //index выходит за рамки равен -1
                    --index;
                }
                temp = BitConverter.ToUInt32(L, 0) ^ temp;
                L = R;
                R = BitConverter.GetBytes(temp);
                //++index;
            }
            byte[] result = new byte[8];
            index = 0;
            for (int i = 0; i < 8; ++i)
            {
                if (i < 4)
                {
                    result[i] = L[i];
                }
                else
                {
                    result[i] = R[index];
                    index++;
                }
            }
            return result;
        }
 
        private void textBox2_TextChanged(object sender, EventArgs e)
        {
            if (lengthKey(textBox2.Text) < 32)
            {
                textBox2.BackColor = Color.Red;
                button1.Enabled = false;
            }
            else
            {
                if (lengthKey(textBox2.Text) > 32)
                {
                    textBox2.BackColor = Color.Red;
                    button1.Enabled = false;
                }
                else
                {
                    textBox2.BackColor = Color.Green;
                    button1.Enabled = true;
                    textBox2.MaxLength = textBox2.TextLength;
                }
            }
 
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            fillingListKey(textBox2.Text);
            fillingListData(textBox1.Text);
           // byte[] temp = Encoding.Default.GetBytes(textBox1.Text);
 
            byte[] t = new byte[8];
            List<byte[]> result = new List<byte[]>();
            for (int i = 0; i < lsData.Count; ++i)
            {
                t = encode(lsData[i]);
                result.Add(t);
            }
            byte[] res = fillingArrayData(result);
            textBox3.Text = Encoding.Default.GetString(res);
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            fillingListKey(textBox2.Text);
            fillingListData(textBox3.Text);
            byte[] temp = Encoding.Default.GetBytes(textBox3.Text);
            byte[] t = new byte[8];
            List<byte[]> result = new List<byte[]>();
            for (int i = 0; i < lsData.Count; ++i)
            {
                t = decode(lsData[i]);
                result.Add(t);
            }
            byte[] res = fillingArrayData(result);
            textBox4.Text = Encoding.Default.GetString(res);
        }
    }
}
Возможно я неверно понял алгоритм? P.S. Если возникли не понимания в коде спрашивайте разъясню: что делает, почему и как

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

textual
Листинг программы
byte[] bKey = {
         0x33,  0x20,  0x6d,  0x54,
         0x32,  0x6c,  0x65,  0x68,
         0x20,  0x65,  0x73,  0x69,
         0x62,  0x6e,  0x73,  0x73,
         0x79,  0x67,  0x61,  0x20,
         0x74,  0x74,  0x67,  0x69,
         0x65,  0x68,  0x65,  0x73,
                 0x73,  0x3d,  0x2C,  0x20
                          };

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


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

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

14   голосов , оценка 4 из 5
Похожие ответы