Алгоритм шифрования ГОСТ 28147-89. Режим простой замены - C#
Формулировка задачи:
Реализовывал алгоритм по wiki. Но что то не то получилось.Вот код:
Возможно я неверно понял алгоритм?
P.S. Если возникли не понимания в коде спрашивайте разъясню: что делает, почему и как
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); } } }
Решение задачи: «Алгоритм шифрования ГОСТ 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 };
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д