Почему мой графический интерфейс останавливается перед чтением из сетевого потока, но отлично работает с - MessageBox.Sow ("");прежде чем читать это? - PullRequest
0 голосов
/ 07 ноября 2019

Я студент факультета компьютерных наук, и это мой второй проект на c #, поэтому я к этому еще не привык, и это мой второй вопрос по stackoverflow ... Мне нужно создать программу с сервером и клиентом, но ихсвязь должна быть безопасной (я использовал Диффи-Хеллмана и AES). Моя программа зависает, когда я пытаюсь прочитать отправленное сообщение через NetworkStream, программа работает нормально, если я добавлю показывать какое-либо сообщение с помощью MessageBox, перед чтением из потока. Также есть ли способ для клиента и сервера генерировать один и тот же AES.IV, кроме моей реализации global IV?

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.IO;
using System.Security.Cryptography;
using System.Linq;

namespace Kodiranje
{
public partial class Form1 : Form
{
    const int port = 22222;
    const string ip = "127.0.0.1";
    IPAddress ipServer = IPAddress.Parse(ip);
    TcpListener server = null;
    TcpClient client = null;
    Thread thServer = null;
    NetworkStream dataStream = null;
    string receivedMessage = "";
    bool? izbira = null;
    Aes myAes = Aes.Create();

    byte[] iv = null;


    public Form1()
    {
        InitializeComponent();
        iv = myAes.IV;
        thServer = new Thread(new ThreadStart(startServer));
        thServer.IsBackground = true;
        thServer.Start();
        myAes.Padding = PaddingMode.PKCS7;
        iv = myAes.IV;
    }

    void startServer() {

        server = new TcpListener(ipServer, port);
        server.Start();
        textBox4.Invoke(new Action(() => textBox4.AppendText("Strežnik: zagnan na: IP: " + ip + ", port:" + port)));
        client = new TcpClient();
        client = server.AcceptTcpClient();
        NetworkStream dataStream = client.GetStream();
        textBox4.Invoke(new Action(() => textBox4.AppendText(Environment.NewLine + "Strežnik: Sprejet nov uporabnik")));


        if (izbira == true)
        {
            byte[] serverPublicKey;
            ECDiffieHellmanCng serverDH = new ECDiffieHellmanCng();
            serverDH.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
            serverDH.HashAlgorithm = CngAlgorithm.Sha256;
            serverPublicKey = serverDH.PublicKey.ToByteArray();



            byte[] message = new byte[1024];
            while (!dataStream.DataAvailable) { }
            if (dataStream.DataAvailable)
                dataStream.Read(message, 0, message.Length);


            byte[] serverCommoneKey = serverDH.DeriveKeyMaterial(CngKey.Import(message, CngKeyBlobFormat.EccPublicBlob));
            textBox4.Invoke(new Action(() => textBox4.AppendText(Environment.NewLine + "Strežnik: Dobil sem sporočilo: " + receivedMessage)));


            dataStream.Write(serverPublicKey, 0, serverPublicKey.Length);

            message = new byte[1024];

            myAes = Aes.Create();
            myAes.Padding = PaddingMode.PKCS7;
            myAes.Key = serverCommoneKey;
            myAes.IV = iv;
            ICryptoTransform encryptor = myAes.CreateEncryptor(myAes.Key, iv);
            byte[] encrypted;
            // Create the streams used for encryption.
            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {
                        //Write all data to the stream.
                        swEncrypt.Write("Serbus deda");

                    }
                    encrypted = msEncrypt.ToArray();
                    int s = encrypted.Length;
                    MessageBox.Show(""); // freezes without message
                    dataStream.Write(encrypted, 0, encrypted.Length);

                } 
            }
        }


        else {
            byte[] message = new byte[1024];
            message = Encoding.UTF8.GetBytes("serbus");
            dataStream.Write(message, 0, message.Length);


        }


    }

    void button1_Click(object sender, EventArgs e) { // happens when client connects to the server
        if (izbira == null) {
            textBox4.Invoke(new Action(() => textBox4.AppendText(Environment.NewLine + "Izbrati morate ali boste datoteko prenesli ali poslali!")));
            return;
        }
        this.button1.Enabled = false;
        client = new TcpClient();
        IPAddress insertedIp = IPAddress.Parse(textBox1.Text);


        byte[] clientPublicKey;
        ECDiffieHellmanCng clientDH = new ECDiffieHellmanCng();
        clientDH.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
        clientDH.HashAlgorithm = CngAlgorithm.Sha256;
        clientPublicKey = clientDH.PublicKey.ToByteArray();


        client.Connect(insertedIp, Convert.ToInt32(textBox3.Text));
        dataStream = client.GetStream();


        if (izbira == true)
        {

            dataStream.Write(clientPublicKey, 0, clientPublicKey.Length);

            byte[] message = new byte[1024];

            MessageBox.Show(""); // freezes without message
            while (true)
            {
                if (dataStream.DataAvailable)
                {

                    dataStream.Read(message, 0, message.Length);
                    textBox4.Invoke(new Action(() => textBox4.AppendText(Environment.NewLine + "Client: Dobil sem sporočilo: " + receivedMessage)));
                    break;
                }
            }
            byte[] clientCommoneKey = clientDH.DeriveKeyMaterial(CngKey.Import(message, CngKeyBlobFormat.EccPublicBlob));




            byte[] encryptedMessage = new byte[16];
            while (!dataStream.DataAvailable) { }
            MessageBox.Show(""); // freezes without message
            dataStream.Read(encryptedMessage, 0, encryptedMessage.Length);
            myAes = Aes.Create();
            myAes.Padding = PaddingMode.PKCS7;
            myAes.Key = clientCommoneKey;
            // Create a decryptor to perform the stream transform.
            ICryptoTransform decryptor = myAes.CreateDecryptor(myAes.Key, iv);

            // Create the streams used for decryption.
            using (MemoryStream msDecrypt = new MemoryStream(encryptedMessage))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {

                        // Read the decrypted bytes from the decrypting stream
                        // and place them in a string.
                        string plaintext;
                        plaintext = srDecrypt.ReadToEnd();
                        MessageBox.Show("Sprejeto sporočilo " + plaintext);

                    }
                }
            }


        }
        else {

            byte[] message = new byte[1024];
            //MessageBox.Show("Serbus");
            while (!dataStream.DataAvailable)
            { }
            dataStream.Read(message, 0, message.Length);

            receivedMessage = Encoding.UTF8.GetString(message);
            textBox4.Invoke(new Action(() => textBox4.AppendText(Environment.NewLine + "Strežnik: Dobil sem sporočilo: " + receivedMessage)));
        }
    }

    void buttonUpload_Click(object sender, EventArgs e) {
        izbira = true;
        this.buttonDownload.Enabled = false;
    }
    void buttonDownload_Click(object sender, EventArgs e) {
        izbira = false;
        this.buttonUpload.Enabled = false;
        this.button2.Text = "Prenesi";
    }



}

}

...