none
Aiuto crittografia (base) chat client-server

    Domanda

  • Volevo realizzare una chat client server, molto semplice, ma allo stesso tempo sicura.
    Pensavo di crittografare utilizzando AES-256bit.
    Io l'ho pensata così, ditemi se sbaglio ovviamente, i vari client inseriscono in una textbox "sicura" le password (che devono essere uguali ovunque) e nelle funzioni di invio, criptano i messaggi (che inserisco in un altra textbox normale), utilizzando la password e li inviano al server; la funzione di ricezione decripta sempre utilizzando sempre la stessa chiave. 
    Il server invece non dovrebbe fare nulla a livello di crittografia.

    La chat prima di aver modificato le funzioni per provare ad applicare la crittografia funzionava.

    Ho provato, ma non so se non funziona a causa della logica o a livello di codice

    Per non complicarmi il lavoro, ho pensato scambiare le password (chiavi) via voce, in quanto sarebbe una chat solo per uso personale.

    Invece ecco come ho modificato le due funzioni di invio e ricezione nel client: 

    Invio:

    // invia il messaggio scritto al server
            private void SendMessage()
            {
                if (txtMessage.Lines.Length >= 1)
                {
                    byte[] passwordBytes = GetPasswordBytes();
                    encrypted_message = AES.Encrypt(txtMessage.Text, passwordBytes);
                    swSender.WriteLine(encrypted_message);
                    swSender.Flush();
                    txtMessage.Lines = null;
                }
                txtMessage.Text = "";
            }

    Ricezione:

    private void ReceiveMessages()
            {
                // Receive the response from the server
                srReceiver = new StreamReader(tcpServer.GetStream());
                // If the first character of the response is 1, connection was successful
                string ConResponse = srReceiver.ReadLine();
                // If the first character is a 1, connection was successful
                if (ConResponse[0] == '1')
                {
                    // Update the form to tell it we are now connected
                    this.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { "Connessione avvenuta con successo!" });
                }
                else // If the first character is not a 1 (probably a 0), the connection was unsuccessful
                {
                    string Reason = "Non connesso: ";
                    // Extract the reason out of the response message. The reason starts at the 3rd character
                    Reason += ConResponse.Substring(2, ConResponse.Length - 2);
                    // Update the form with the reason why we couldn't connect
                    this.Invoke(new CloseConnectionCallback(this.CloseConnection), new object[] { Reason });
                    // Exit the method
                    return;
                }
                // While we are successfully connected, read incoming lines from the server
                while (Connected == true)
                {
                        try
                        {
                            // Show the messages decrypted in the log TextBox
                            this.Invoke(new UpdateLogCallback(this.MessageUpdateLog), new object[] { srReceiver.ReadLine() });
                            
                        }
                        catch
                        {
                            try
                            {
                            this.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { srReceiver.ReadLine() });
                            }
                            catch { }
                        }
                }
            }
    
            // This method is called from a different thread in order to update the log TextBox
            private void UpdateLog(string strMessage)
            {
                txtLog.AppendText(strMessage + "\r\n");
            }
            
            //Decittografia dei messaggi in arrivo dagli altri client
            private void MessageUpdateLog(string strMessage_de)
            {
                byte[] passwordBytes = GetPasswordBytes();
                strMessage_de = AES.Decrypt(strMessage_de, passwordBytes);
                // Append text also scrolls the TextBox to the bottom each time
                txtLog.AppendText(strMessage_de + "\r\n");
            }


    martedì 10 maggio 2016 18:17

Risposte

  • Le funzioni di invio e ricezione funzionano correttamente con i messaggi in chiaro?

    se si il problema non è sulla funzione di invio e ricezione in quanto tale ma sui dati.

    Ricordo un problema non banale che abbiamo avuto alcuni anni fa nello sviluppo di un sistema di trasmissione messaggi con i servizi HTTP di .Net causati dal BOM che creava problemi sull'interpretazione dei dati (nel nostro caso un parse XML o forse JSON) in ogni caso a causa del BOM inserito nelle stringhe a nostra insaputa :P la stringa ricevuta dava errore di serializzazione ed esplodeva tutto...

    Prova a verificare se riesci con uno strumento di sniffing http che stringa parte e che stringa arriva. http://www.telerik.com/fiddler questo dovrebbe aiutare

    Questo è invece http://encyclopedia.thefreedictionary.com/Byte+Order+Mark

    se ti stai chiedendo cosa diamine è il BOM di cui parlo prima.


    Sabrina C. - http://www.dotnetwork.it

    giovedì 12 maggio 2016 14:18
  • I tuoi metodi potrebbero anche essere perfetti, ma non credo di poterti dire molto solo guardando il codice.

    Ti potrei consigliare di dare un occhiata a un altro esempio che so funzionare correttamente, anche se in un contesto diverso.

    In questo caso si tratta di un sistema di comunicazione via HTTP fra un servizio ed una applicazione windows forms per poter monitorare il servizio stesso.

    Non so se può risolvere il tuo problema, (davvero controlla gli stream che partono e arrivano prima di tutto) ma magari guardare un esempio funzionante ti può dare delle idee.

    Scambio messaggi HTTP Servizio/Console

    L'articolo qui sopra implementa una "chat" fra il servizio e l'applicazione windows che fa da console di controllo del servizio stesso.


    Sabrina C. - http://www.dotnetwork.it


    venerdì 13 maggio 2016 15:15

Tutte le risposte

  • Non so se questo ti possa aiutare, ma per la crittografia semplice con l'uso della password io utilizzo il CryptoStream e la classe Rijndael e ottengo una crittografia a 256 bit.

    Ti ho postato una applicazione esempio che crittografa e decrittografa il testo usando una password nota a questo link:

    Due metodi helper per la crittografia AES

    Se hai ulteriori dubbi chiedi e cercheremo di rispondere.


    Sabrina C. - http://www.dotnetwork.it

    mercoledì 11 maggio 2016 12:58
  • Ti ringrazio per la risposta, forse però mi sono espresso male, e mi scuso, la crittografia di per se funziona, però è l'insieme del programma che non funziona:

    il client invia i testi criptati, però, l'altro client che riceve non decripta nulla.

    Ribadisco che le funzioni di crittografia e decrittografia AES le so usare, però in questo contesto non riesco a capire il problema...

    mercoledì 11 maggio 2016 20:29
  • Se il client ricevente non decripta nulla, c'è un errore nei metodi di crittografia e decrittografia che utilizzi, oppure lo stream dati che viene inviato non è esattamente identico a quello prodotto dalla funzione di crittografia, perché sfortunatamente, con la crittografia anche un solo bit di differenza non permette di decrittografare correttamente.

    Questo è il motivo per cui ho speso una mezz'ora a scrivere un esempio funzionante in modo che tu possa scaricarlo e dargli un occhiata per verificare cosa c'è di diverso fra quello che faccio io e quello che hai fatto tu, con maggiori probabilità di trovare il punto in cui il problema si verifica.

    ;o)


    Sabrina C. - http://www.dotnetwork.it

    giovedì 12 maggio 2016 08:52
  • Non avevo capito che avevi fatto quell' esempio per me! Gentilissima :)

    Comunque nei metodi di crittografia e decrittografia che uso non dovrebbero esserci problemi in quanto tempo fa avevo fatto un programma simile al tuo di esempio (che hai postato nel sito) e funzionava alla perfezione.

    Nelle funzioni di invio e ricezione che ho postato ci sono problemi? Ti andrebbe bene se ti inviassi il mio programma completo?

    Grazie ancora.

    giovedì 12 maggio 2016 13:25
  • Le funzioni di invio e ricezione funzionano correttamente con i messaggi in chiaro?

    se si il problema non è sulla funzione di invio e ricezione in quanto tale ma sui dati.

    Ricordo un problema non banale che abbiamo avuto alcuni anni fa nello sviluppo di un sistema di trasmissione messaggi con i servizi HTTP di .Net causati dal BOM che creava problemi sull'interpretazione dei dati (nel nostro caso un parse XML o forse JSON) in ogni caso a causa del BOM inserito nelle stringhe a nostra insaputa :P la stringa ricevuta dava errore di serializzazione ed esplodeva tutto...

    Prova a verificare se riesci con uno strumento di sniffing http che stringa parte e che stringa arriva. http://www.telerik.com/fiddler questo dovrebbe aiutare

    Questo è invece http://encyclopedia.thefreedictionary.com/Byte+Order+Mark

    se ti stai chiedendo cosa diamine è il BOM di cui parlo prima.


    Sabrina C. - http://www.dotnetwork.it

    giovedì 12 maggio 2016 14:18
  • In chiaro si. Però le funzioni le ho modificate da quando la chat funzionava in chiaro.

    Ecco le "vecchie"

    Invio: 

    // Sends the message typed in to the server
            private void SendMessage()
            {
                if (txtMessage.Lines.Length >= 1)
                {
                    swSender.WriteLine(txtMessage.Text);
                    swSender.Flush();
                    txtMessage.Lines = null;
                }
                txtMessage.Text = "";
            }

    Ricezione:

    private void ReceiveMessages()
            {
                // Receive the response from the server
                srReceiver = new StreamReader(tcpServer.GetStream());
                // If the first character of the response is 1, connection was successful
                string ConResponse = srReceiver.ReadLine();
                // If the first character is a 1, connection was successful
                if (ConResponse[0] == '1')
                {
                    // Update the form to tell it we are now connected
                    this.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { "Connessione avvenuta con successo!" });
                }
                else // If the first character is not a 1 (probably a 0), the connection was unsuccessful
                {
                    string Reason = "Non connesso: ";
                    // Extract the reason out of the response message. The reason starts at the 3rd character
                    Reason += ConResponse.Substring(2, ConResponse.Length - 2);
                    // Update the form with the reason why we couldn't connect
                    this.Invoke(new CloseConnectionCallback(this.CloseConnection), new object[] { Reason });
                    // Exit the method
                    return;
                }
                // While we are successfully connected, read incoming lines from the server
                while (Connected)
                {   try
                    {
                        // Show the messages in the log TextBox
                        this.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { srReceiver.ReadLine() });
                    }
                    catch { }
                }
            }
    
            // This method is called from a different thread in order to update the log TextBox
            private void UpdateLog(string strMessage)
            {
                // Append text also scrolls the TextBox to the bottom each time
                txtLog.AppendText(strMessage + "\r\n");
            }

    giovedì 12 maggio 2016 14:48
  • I tuoi metodi potrebbero anche essere perfetti, ma non credo di poterti dire molto solo guardando il codice.

    Ti potrei consigliare di dare un occhiata a un altro esempio che so funzionare correttamente, anche se in un contesto diverso.

    In questo caso si tratta di un sistema di comunicazione via HTTP fra un servizio ed una applicazione windows forms per poter monitorare il servizio stesso.

    Non so se può risolvere il tuo problema, (davvero controlla gli stream che partono e arrivano prima di tutto) ma magari guardare un esempio funzionante ti può dare delle idee.

    Scambio messaggi HTTP Servizio/Console

    L'articolo qui sopra implementa una "chat" fra il servizio e l'applicazione windows che fa da console di controllo del servizio stesso.


    Sabrina C. - http://www.dotnetwork.it


    venerdì 13 maggio 2016 15:15
  • Grazie, appena avrò lo leggerò!
    lunedì 16 maggio 2016 16:21