user34537
user34537

Reputation:

Asymmetrical TCP encryption C#

I would like to write a client and server app which uses a tcp socket to communicate. However I do not need a cert as the users don't care who the other is. But i do need asymmetrical encryption so no one can snoop. I can't think of a way to share the symmetrical keys w/o using RSA but anyways i think i should be using SSL with TCP?

What is the most way to create an SSL/TCP connection in C#? I imagine i either specify no cert or dynamically create one of the fly (but they should be throwaway...). What is the most simple way to implement it? I tried simply adding a sslstream to my tcp stream but that doesnt cut it (i get stream not readable errors). Heres my simple code so far

    {
        Thread serverThread = new Thread((ThreadStart)delegate
        {
            TcpListener listener = new TcpListener(1234);
            listener.Start();
            using (TcpClient client = listener.AcceptTcpClient())
            //using (var sslstream = client.GetStream())
            using (var sslstream = new System.Net.Security.SslStream(client.GetStream(), true))
            using (StreamReader reader = new StreamReader(sslstream))
            using (StreamWriter writer = new StreamWriter(sslstream))
            {
                writer.AutoFlush = true;
                string inputLine;
                while ((inputLine = reader.ReadLine()) != null)
                {
                    writer.WriteLine(inputLine);
                }
            }
        });
        serverThread.Start();
        {
            string[] linesToSend = new string[] { "foo", "bar", "ack" };
            using (TcpClient client = new TcpClient("127.0.0.1", 1234))
            //using (var sslstream = client.GetStream())
            using (var sslstream = new System.Net.Security.SslStream(client.GetStream(), true))
            using (StreamReader reader = new StreamReader(sslstream))
            using (StreamWriter writer = new StreamWriter(sslstream))
            {
                writer.AutoFlush = true;
                foreach (string lineToSend in linesToSend)
                {
                    Console.WriteLine("Sending to server: {0}", lineToSend);
                    writer.WriteLine(lineToSend);
                    string lineWeRead = reader.ReadLine();
                    Console.WriteLine("Received from server: {0}", lineWeRead);
                    //Thread.Sleep(2000); // just for effect
                }
                Console.WriteLine("Client is disconnecting from server");
            }
        }
        serverThread.Join();
    }

Upvotes: 4

Views: 3365

Answers (1)

Remus Rusanu
Remus Rusanu

Reputation: 294267

You need to provide an implementation for LocalCertificateSelectionCallback to pick the certificate to use and you need to provide an implementation for RemoteCertificateValidationCallback to accept the self-signed certificate used by the peer.

To create a self-signed certificate (ie. throw-away) see Creating a self-signed certificate in C#.

There is also a step-by-step example here on SO at Using SSL and SslStream for peer to peer authentication.

Make sure you comprehend the implications, ie. a man-in-the-middle can ear drop your traffic as you do not actually validate the certificate presented. In other words this is not at all a form of authentication (as suggested in the SO linked answer) but just a way to obtain a private communication with somebody, but you don't really know with whom exactly. An alternative would be to use a root certificate to sign each throw away certificate used and validate the certificate chain in the client, but that would complicate significantly the generation of the cert compared with the blog link.

Upvotes: 5

Related Questions