Чат с шифрованием по Плейферу. Как передать ключ для формирования матрицы? - C#
Формулировка задачи:
Добрый вечер!
Вот код чата
сообщения между собеседниками должны передаваться зашифрованными
причем ключ у каждого собеседника свой (ник = ключ)
на основании ключа формируется матрица для шифровки по Плейферу
сообщение шифруется и передается другому собеседнику
моя проблема в том, что я не знаю как получить ключ от собеседника чтобы дешифровать его сообщение
вот код:
кто может помогите пожалста моему горю
голова кругом уже
а завтра сдаваться (
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
namespace Chat_APP
{
public partial class Form1 : Form
{
Socket socket;
EndPoint epLocal, epRemote;
// все символы алфавитов английские русские + знаки, вся длина строки = 160
String ABC = "ABCDEFGHIJKLMNOPQRSTUVWXYZАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯabcdefghijklmnopqrstuvwxyzабвгдеёжзийклмнопрстуфхцчшщъыьэюя !@\"#№$;%^:&?*()-_+={}[]\\/<>.,~`0123456789";
// матрица для шифровки расшифровки
// формируется динамически на основании переданного Ключа и строки ABC
// строку из 160 символов будем разбивать на двумерный массив размером 10x16
char[,] Matrix = new char[10, 16];
static public string Ключ;
//
public Form1()
{
InitializeComponent();
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
// IP = 127.0.0.1 для локальной сети
textLocalIP.Text = "127.0.0.1"; //ПолучитьЛокальныйАдресIP();
textFriendIP.Text = "127.0.0.1"; //ПолучитьЛокальныйАдресIP();
//// если связь НЕ по локальной сети то нужно получать IP
//textLocalIP.Text = ПолучитьЛокальныйАдресIP();
//textFriendIP.Text = ПолучитьЛокальныйАдресIP();
// Номер порта = 15000 можно любой другой
textLocalPort.Text = "15000"; // мой порт - локальный
textFriendPort.Text = "15001"; // порт собеседника - удаленный
// во 2-ом окне нужно ввести порты наоборот:
// мой порт = "15001"
// порт собеседника = "15000"
}
// Подключение к сети
private void buttonStart_Click(object sender, EventArgs e)
{
try
{
epLocal = new IPEndPoint(IPAddress.Parse(textLocalIP.Text), Convert.ToInt32(textLocalPort.Text));
socket.Bind(epLocal);
epRemote = new IPEndPoint(IPAddress.Parse(textFriendIP.Text), Convert.ToInt32(textFriendPort.Text));
socket.Connect(epRemote);
byte[] buffer = new byte[1500];
socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(ПолучитьСообщение), buffer);
buttonStart.Text = "Подключён";
buttonStart.Enabled = false;
// разрешаем поле и кнопку отправки сообщений
textMessage.Enabled = true;
buttonSend.Enabled = true;
// переводим фокус на ввод сообщения
textMessage.Focus();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
private void buttonSend_Click(object sender, EventArgs e)
{
ОтправитьСообщение();
}
private void textMessage_KeyDown(object sender, KeyEventArgs e)
{
// если нажата Enter в поле сообщения то отправляем сообщение
if (e.KeyCode == Keys.Enter)
{
ОтправитьСообщение();
}
}
// Отправка сообщения
private void ОтправитьСообщение()
{
try
{
Ключ = textBoxNick.Text; // глобальный
// конвертация текста в байты для передачи
byte[] byteMsg = new byte[1500];
///
string Key = textBoxNick.Text; // ключ = Ник
//string SendMessage = textMessage.Text;
string Сообщение = textMessage.Text;
string ТекстДляОтправки = Key + "Ё" + textMessage.Text; // отправляемая строка
//// шифровка текста
//СоздатьМатрицу(Key);
string ЗашифрованноеСообщение = ЗашифроватьТекст(Сообщение, Key);
textBoxEncodedMsg.Text = ЗашифрованноеСообщение;
string sKey = ПолучитьКлючИзСообщения(ТекстДляОтправки);
string sMsg = ПолучитьТекстИзСообщения(ТекстДляОтправки);
textBoxDecodedMsg.Text = РасшифроватьТекст(ЗашифрованноеСообщение, Key);
string ЗашифрованныйТекстДляОтправки = ЗашифроватьТекст(ТекстДляОтправки, Key);
// перевод строки в набор битов
//byteMsg = Encoding.Default.GetBytes(ЗашифрованныйТекстДляОтправки);
//byteMsg = Encoding.Unicode.GetBytes(Сообщение);
byteMsg = Encoding.Unicode.GetBytes(ЗашифрованныйТекстДляОтправки);
socket.Send(byteMsg); // отправка сообщения
listMessage.Items.Add("Я: " + Сообщение);
//listMessage.Items.Add(textBoxNick.Text + ": " + textMessage.Text);
textMessage.Clear();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
// получение сообщения
private void ПолучитьСообщение(IAsyncResult aresut)
{
try
{
int size = socket.EndReceiveFrom(aresut, ref epRemote);
if (size > 0)
{
byte[] byteПолученныеДанные = new byte[1464];
byteПолученныеДанные = (byte[])aresut.AsyncState;
//string ПолученныйТекст = Encoding.Default.GetString(byteПолученныеДанные);
string ПолученныйТекст = Encoding.Unicode.GetString(byteПолученныеДанные);
ПолученныйТекст = ПолученныйТекст.TrimEnd();
// Дешифровка
string РасшифрованныйТекст = РасшифроватьТекст(ПолученныйТекст, Ключ);
// выделить ключ и текст сообщения из полученных данных
string Кеу = ПолучитьКлючИзСообщения(ПолученныйТекст);
string РасшифрованноеСообщение = ПолучитьТекстИзСообщения(ПолученныйТекст);
// вывести в список сообщений
//listMessage.Items.Add("Друг: " + receivedMessage);
////listMessage.Items.Add(textBoxNick.Text + ": " + receivedMessage);
//listMessage.Items.Add(strReceivedMessage);
listMessage.Items.Add(Кеу + ": " + РасшифрованноеСообщение);
}
byte[] buffer = new byte[1500];
socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(ПолучитьСообщение), buffer);
}
catch (Exception exp)
{
MessageBox.Show(exp.ToString());
}
}
// Получить IP адрес компьютера
private string ПолучитьЛокальныйАдресIP()
{
IPHostEntry host;
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
return ip.ToString(); // возвращаем сетевой IP
}
return "127.0.0.1"; // возвращаем локальный IP
}
// Выход
private void buttonExit_Click(object sender, EventArgs e)
{
Close();
}
// -----------------------------------------------------------------
#region Шифрование-Дешифрование
// Получить ключ из полученной строки
// Ключ в полученном сообщении отделен символом Ё от текста
string ПолучитьКлючИзСообщения(string strMsg)
{
// разбиваем сообщение на массив строк по символу Ё
string[] arrMsg = strMsg.Split('Ё');
string key = arrMsg[0]; // ключ
string msg = arrMsg[1]; // сообщение
return key;
}
// Получить только текст сообщения из полученной строки без ключа
// Ключ в полученном сообщении отделен символом Ё от текста
string ПолучитьТекстИзСообщения(string strMsg)
{
// разбиваем сообщение на массив строк по символу Ё
string[] arrMsg = strMsg.Split('Ё');
string key = arrMsg[0]; // ключ
string msg = arrMsg[1]; // сообщение
return msg;
}
// Проверка Шифрования
private void buttonEncode_Click(object sender, EventArgs e)
{
string Key = textBoxNick.Text; // ключ = Ник
//СоздатьМатрицу(Key);
if (textBoxDecodedMsg.Text != "")
{
string msg = textBoxDecodedMsg.Text.TrimEnd();
textBoxEncodedMsg.Text = ЗашифроватьТекст(msg, Key);
}
}
// Проверка ДеШифрования
private void buttonDecode_Click(object sender, EventArgs e)
{
string Key = textBoxNick.Text; // ключ = Ник
//СоздатьМатрицу(Key);
if (textBoxEncodedMsg.Text != "")
{
string msg = textBoxEncodedMsg.Text;
textBoxDecodedMsg.Text = РасшифроватьТекст(msg, Key);
}
}
// Функция создания матрицы
void СоздатьМатрицу(string Key)
{
String Alphabet = "";
// добавляем ключ
for (int i = 0; i < Key.Length; i++)
{
if (Alphabet.IndexOf(Key[i]) == -1)
Alphabet += Key[i];
}
// добавляем остальные символы из ABC
for (int i = 0; i < ABC.Length; i++)
{
if (Alphabet.IndexOf(ABC[i]) == -1)
Alphabet += ABC[i];
}
// заполняем массив букв решетки
int num = 0;
for (int i = 0; i < 10; i++)
for (int j = 0; j < 16; j++)
{
Matrix[i, j] = Alphabet[num];
num++;
}
}
// ------------------------
// Шифрование текста
string ЗашифроватьТекст(string Text, string Key)
{
СоздатьМатрицу(Key);
if (Text.Length % 2 != 0)
Text = Text + " ";
string Результат = "";
// индексы букв в столбцах
int ind_x1 = 0;
int ind_y1 = 0;
int ind_x2 = 0;
int ind_y2 = 0;
int k = 0;
while (k < Text.Length)
{
for (int i = 0; i < 10; i++)
for (int j = 0; j < 16; j++)
{
if (Text[k] == Matrix[i, j])
{
ind_x1 = i;
ind_y1 = j;
}
if (Text[k + 1] == Matrix[i, j])
{
ind_x2 = i;
ind_y2 = j;
}
}
// Если буквы находятся в одной строке
if (ind_x1 == ind_x2)
{
if (ind_y1 == 15)
{
Результат += Matrix[ind_x1, 0];
Результат += Matrix[ind_x2, ind_y2 + 1];
}
else
if (ind_y2 == 15)
{
Результат += Matrix[ind_x1, ind_y1 + 1];
Результат += Matrix[ind_x2, 0];
}
else
{
Результат += Matrix[ind_x1, ind_y1 + 1];
Результат += Matrix[ind_x2, ind_y2 + 1];
}
}
// Если буквы находятся в одном столбце
if (ind_y1 == ind_y2)
{
if (ind_x1 == 9)
{
Результат += Matrix[0, ind_y1];
Результат += Matrix[ind_x2 + 1, ind_y2];
}
else
if (ind_x2 == 9)
{
Результат += Matrix[ind_x1 + 1, ind_y1];
Результат += Matrix[0, ind_y2];
}
else
{
Результат += Matrix[ind_x1 + 1, ind_y1];
Результат += Matrix[ind_x2 + 1, ind_y2];
}
}
// Если буквы находятся в разных строках и разных столбцах
if ((ind_x1 != ind_x2) && (ind_y1 != ind_y2))
{
Результат += Matrix[ind_x1, ind_y2];
Результат += Matrix[ind_x2, ind_y1];
}
k = k + 2;
}
return Результат;
}
// ---------------------------
// Дешифрование текста
string РасшифроватьТекст(string Text, string Key)
{
СоздатьМатрицу(Key);
string Результат = "";
// индексы букв в столбцах
int ind_x1 = 0;
int ind_y1 = 0;
int ind_x2 = 0;
int ind_y2 = 0;
int k = 0;
while (k < Text.Length)
{
for (int i = 0; i < 10; i++)
for (int j = 0; j < 16; j++)
{
if (Text[k] == Matrix[i, j])
{
ind_x1 = i;
ind_y1 = j;
}
if (Text[k + 1] == Matrix[i, j])
{
ind_x2 = i;
ind_y2 = j;
}
}
// Если буквы находятся в одной строке
if (ind_x1 == ind_x2)
{
if (ind_y1 == 0)
{
Результат += Matrix[ind_x1, 15];
Результат += Matrix[ind_x2, ind_y2 - 1];
}
else
if (ind_y2 == 0)
{
Результат += Matrix[ind_x1, ind_y1 - 1];
Результат += Matrix[ind_x2, 15];
}
else
{
Результат += Matrix[ind_x1, ind_y1 - 1];
Результат += Matrix[ind_x2, ind_y2 - 1];
}
}
// Если буквы находятся в одном столбце
if (ind_y1 == ind_y2)
{
if (ind_x1 == 0)
{
Результат += Matrix[9, ind_y1];
Результат += Matrix[ind_x2 - 1, ind_y2];
}
else
if (ind_x2 == 0)
{
Результат += Matrix[ind_x1 - 1, ind_y1];
Результат += Matrix[9, ind_y2];
}
else
{
Результат += Matrix[ind_x1 - 1, ind_y1];
Результат += Matrix[ind_x2 - 1, ind_y2];
}
}
// Если буквы находятся в разных строках и разных столбцах
if ((ind_x1 != ind_x2) && (ind_y1 != ind_y2))
{
Результат += Matrix[ind_x1, ind_y2];
Результат += Matrix[ind_x2, ind_y1];
}
k = k + 2;
}
return Результат;
}
#endregion //Шифрование-Дешифрование
}
}Решение задачи: «Чат с шифрованием по Плейферу. Как передать ключ для формирования матрицы?»
textual
Листинг программы
private void ПолучитьСообщение(IAsyncResult aresut)
{
string Кеу, РасшифрованноеСообщение;
try
{
int size = socket.EndReceiveFrom(aresut, ref epRemote);
if (size > 0)
{
byte[] byteПолученныеДанные = new byte[1464];
byteПолученныеДанные = (byte[])aresut.AsyncState;
string ПолученныйТекст = Encoding.Unicode.GetString(byteПолученныеДанные);
// выделить ключ и текст сообщения из полученных данных
Кеу = ПолучитьКлючИзСообщения(ПолученныйТекст);
string ПолученноеСообщение = ПолучитьТекстИзСообщения(ПолученныйТекст);
// Дешифровка
РасшифрованноеСообщение = РасшифроватьТекст(ПолученноеСообщение, Кеу);
// вывести в список сообщений
listMessage.Items.Add(Кеу + ": " + РасшифрованноеСообщение); //<- вот здесь выбрасывает исключение см. картинку
}
byte[] buffer = new byte[1500];
socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(ПолучитьСообщение), buffer);
}
catch (Exception exp)
{
MessageBox.Show(exp.ToString());
}
}