Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6622553
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 25, 20262026-05-25T21:25:16+00:00 2026-05-25T21:25:16+00:00

I need to send confidential data to a server over a TCP connection. I

  • 0

I need to send confidential data to a server over a TCP connection. I have done a lot of researching and I understand the theoretical part. Based on what I have researched I want to do the following:

Note there is a server and a client: (we assume that public keys of either the client or server can be obtain by anyone)

  1. client creates his public and private key. He is able to encrypt with his private key and decrypt with his public key.

  2. server creates his public and private keys. private key is used to decrypt messages and public key is used to encrypt messages. (note is the other way around as with the client)

  3. the client get’s the server’s public key. client then will be able to encrypt messages with that key and the only one that will be able to decrypt that message would be the server’s private key.

  4. since the server needs to be certain that the message comes from that specific client then the client will encrypt his name (signature) with his private key.

  5. so the client message will contain: data to be send, client’s public key, client name encrypted with the client’s private key.

  6. the client will encrypt the message with the public key from the server. client will then send that message to the server.

  7. the server will decrypt the message it just received with his private key.

  8. once the message is decrypted it will contain the data (info), encrypted signature, public key from client.

  9. finally, the server will decrypt the client signature with the public key that was contained on the message to verify that the message is from that client.


OK so this is how asymmetric cryptography works. I have also researched about the classes that enable you to create this key pairs with the .NET framework. The classes that I researched that enable you do create this public and private key pairs are:

System.Security.Cryptography.DES
System.Security.Cryptography.DSACryptoServiceProvider 
System.Security.Cryptography.ECDsa 
System.Security.Cryptography.ECDsaCng 
System.Security.Cryptography.ECDiffieHellman 
System.Security.Cryptography.ECDiffieHellmanCng 
System.Security.Cryptography.RSA 
System.Security.Cryptography.RSACryptoServiceProvider 

so now my problems comes on how do I use one of this classes to do it with C#? I understand how the theoretical part works but how do I do what I just described with code. I have researched for some examples but I am having a hard time understanding them.

here is one example that I found that I believe does what I described:

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Example
{
    class Program
    {
        static CngKey aliceKey;
        static CngKey bobKey;
        static byte[] alicePubKeyBlob;
        static byte[] bobPubKeyBlob;

        static void Main()
        {
            CreateKeys();
            byte[] encrytpedData = AliceSendsData("secret message");
            BobReceivesData(encrytpedData);

            Console.Read();

        }

        private static void CreateKeys()
        {
            aliceKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256);
            bobKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256);
            alicePubKeyBlob = aliceKey.Export(CngKeyBlobFormat.EccPublicBlob);
            bobPubKeyBlob = bobKey.Export(CngKeyBlobFormat.EccPublicBlob);
        }

        private static byte[] AliceSendsData(string message)
        {
            Console.WriteLine("Alice sends message: {0}", message);
            byte[] rawData = Encoding.UTF8.GetBytes(message);
            byte[] encryptedData = null;

            using (var aliceAlgorithm = new ECDiffieHellmanCng(aliceKey))
            using (CngKey bobPubKey = CngKey.Import(bobPubKeyBlob,
                  CngKeyBlobFormat.EccPublicBlob))
            {
                byte[] symmKey = aliceAlgorithm.DeriveKeyMaterial(bobPubKey);
                Console.WriteLine("Alice creates this symmetric key with " +
                      "Bobs public key information: {0}",
                      Convert.ToBase64String(symmKey));

                using (var aes = new AesCryptoServiceProvider())
                {
                    aes.Key = symmKey;
                    aes.GenerateIV();
                    using (ICryptoTransform encryptor = aes.CreateEncryptor())
                    using (MemoryStream ms = new MemoryStream())
                    {
                        // create CryptoStream and encrypt data to send
                        var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);

                        // write initialization vector not encrypted
                        ms.Write(aes.IV, 0, aes.IV.Length);
                        cs.Write(rawData, 0, rawData.Length);
                        cs.Close();
                        encryptedData = ms.ToArray();
                    }
                    aes.Clear();
                }
            }
            Console.WriteLine("Alice: message is encrypted: {0}",
                  Convert.ToBase64String(encryptedData)); ;
            Console.WriteLine();
            return encryptedData;
        }

        private static void BobReceivesData(byte[] encryptedData)
        {
            Console.WriteLine("Bob receives encrypted data");
            byte[] rawData = null;

            var aes = new AesCryptoServiceProvider();

            int nBytes = aes.BlockSize >> 3;
            byte[] iv = new byte[nBytes];
            for (int i = 0; i < iv.Length; i++)
                iv[i] = encryptedData[i];

            using (var bobAlgorithm = new ECDiffieHellmanCng(bobKey))
            using (CngKey alicePubKey = CngKey.Import(alicePubKeyBlob,
                  CngKeyBlobFormat.EccPublicBlob))
            {
                byte[] symmKey = bobAlgorithm.DeriveKeyMaterial(alicePubKey);
                Console.WriteLine("Bob creates this symmetric key with " +
                      "Alices public key information: {0}",
                      Convert.ToBase64String(symmKey));

                aes.Key = symmKey;
                aes.IV = iv;

                using (ICryptoTransform decryptor = aes.CreateDecryptor())
                using (MemoryStream ms = new MemoryStream())
                {
                    var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write);
                    cs.Write(encryptedData, nBytes, encryptedData.Length - nBytes);
                    cs.Close();

                    rawData = ms.ToArray();

                    Console.WriteLine("Bob decrypts message to: {0}",
                          Encoding.UTF8.GetString(rawData));
                }
                aes.Clear();
            }
        }
    }
}

In this program I believe the client is Alice and the server is Bob. I have to split this program into two parts. I am having a hard time understanding it and if I give it a try most likely I will make it work. Anyways how can I split this program into a server side code and client side code. I know how to send bytes between server and client. But I don’t want to make it work without understanding what is going on. maybe you guys can show me an easier example.


EDIT

I managed to separate the code: here is the server code (the ip address of my computer happened to be 192.168.0.120) :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Security.Cryptography;
using System.IO;


namespace ServerListener
{
    class Program
    {
        static TcpListener server;


        //static CngKey aliceKey;
        static CngKey bobKey;
        static byte[] alicePubKeyBlob;
        static byte[] bobPubKeyBlob;

        static void Main(string[] args)
        {

            CreateKeys();

            IPAddress ipAddress = IPAddress.Parse("192.168.0.120");
            server = new TcpListener(ipAddress, 54540);
            server.Start();
            var client = server.AcceptTcpClient();
            var stream = client.GetStream();

            alicePubKeyBlob = new byte[bobPubKeyBlob.Length];
            stream.Read(alicePubKeyBlob, 0, alicePubKeyBlob.Length);

            stream.Write(bobPubKeyBlob, 0, bobPubKeyBlob.Length);

            byte[] encrytpedData = new byte[32];

            stream.Read(encrytpedData, 0, encrytpedData.Length);

            BobReceivesData(encrytpedData);


        }

        private static void CreateKeys()
        {
            //aliceKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256);
            bobKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256);
            //alicePubKeyBlob = aliceKey.Export(CngKeyBlobFormat.EccPublicBlob);
            bobPubKeyBlob = bobKey.Export(CngKeyBlobFormat.EccPublicBlob);
        }


        private static void BobReceivesData(byte[] encryptedData)
        {
            Console.WriteLine("Bob receives encrypted data");
            byte[] rawData = null;

            var aes = new AesCryptoServiceProvider();

            int nBytes = aes.BlockSize >> 3;
            byte[] iv = new byte[nBytes];
            for (int i = 0; i < iv.Length; i++)
                iv[i] = encryptedData[i];

            using (var bobAlgorithm = new ECDiffieHellmanCng(bobKey))
            using (CngKey alicePubKey = CngKey.Import(alicePubKeyBlob,
                  CngKeyBlobFormat.EccPublicBlob))
            {
                byte[] symmKey = bobAlgorithm.DeriveKeyMaterial(alicePubKey);
                Console.WriteLine("Bob creates this symmetric key with " +
                      "Alices public key information: {0}",
                      Convert.ToBase64String(symmKey));

                aes.Key = symmKey;
                aes.IV = iv;

                using (ICryptoTransform decryptor = aes.CreateDecryptor())
                using (MemoryStream ms = new MemoryStream())
                {
                    var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write);
                    cs.Write(encryptedData, nBytes, encryptedData.Length - nBytes);
                    cs.Close();

                    rawData = ms.ToArray();

                    Console.WriteLine("Bob decrypts message to: {0}",
                          Encoding.UTF8.GetString(rawData));
                }
                aes.Clear();
            }
        }
    }
}

and here is the client code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Security.Cryptography;
using System.IO;

namespace ClientAlice
{
    class Program
    {
        static CngKey aliceKey;
        //static CngKey bobKey;
        static byte[] alicePubKeyBlob;
        static byte[] bobPubKeyBlob;

        static void Main(string[] args)
        {

            CreateKeys();
            bobPubKeyBlob = new byte[alicePubKeyBlob.Length];

            TcpClient alice = new TcpClient("192.168.0.120", 54540);

            var stream = alice.GetStream();
            stream.Write(alicePubKeyBlob, 0, alicePubKeyBlob.Length);

            stream.Read(bobPubKeyBlob, 0, bobPubKeyBlob.Length);


            byte[] encrytpedData = AliceSendsData(":)");

            stream.Write(encrytpedData, 0, encrytpedData.Length);


        }


        private static void CreateKeys()
        {
            aliceKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256);
            //bobKey = CngKey.Create(CngAlgorithm.ECDiffieHellmanP256);
            alicePubKeyBlob = aliceKey.Export(CngKeyBlobFormat.EccPublicBlob);
            //bobPubKeyBlob = bobKey.Export(CngKeyBlobFormat.EccPublicBlob);
        }

        private static byte[] AliceSendsData(string message)
        {
            Console.WriteLine("Alice sends message: {0}", message);
            byte[] rawData = Encoding.UTF8.GetBytes(message);
            byte[] encryptedData = null;

            using (var aliceAlgorithm = new ECDiffieHellmanCng(aliceKey))
            using (CngKey bobPubKey = CngKey.Import(bobPubKeyBlob,
                  CngKeyBlobFormat.EccPublicBlob))
            {
                byte[] symmKey = aliceAlgorithm.DeriveKeyMaterial(bobPubKey);
                Console.WriteLine("Alice creates this symmetric key with " +
                      "Bobs public key information: {0}",
                      Convert.ToBase64String(symmKey));

                using (var aes = new AesCryptoServiceProvider())
                {
                    aes.Key = symmKey;
                    aes.GenerateIV();
                    using (ICryptoTransform encryptor = aes.CreateEncryptor())
                    using (MemoryStream ms = new MemoryStream())
                    {
                        // create CryptoStream and encrypt data to send
                        var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);

                        // write initialization vector not encrypted
                        ms.Write(aes.IV, 0, aes.IV.Length);
                        cs.Write(rawData, 0, rawData.Length);
                        cs.Close();
                        encryptedData = ms.ToArray();
                    }
                    aes.Clear();
                }
            }
            Console.WriteLine("Alice: message is encrypted: {0}",
                  Convert.ToBase64String(encryptedData)); ;
            Console.WriteLine();
            return encryptedData;
        }
    }
}

I thinks it is pretty secure. Every time it sends a different byte array although sending the same info!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-25T21:25:17+00:00Added an answer on May 25, 2026 at 9:25 pm

    As you note, you are a beginner at crypto. If this is a fun toy project to learn about crypto, great. If this is real production code you are going to implement it insecurely. You should be using off-the-shelf tools like SSL/HTTPS/whatever to solve this problem rather than doing it wrong yourself.

    I’ll take this opportunity to point out areas where your sketch is fatally weak.

    3) the client get’s the server’s public key.

    OK. How? This is the most important step. The security of the entire system relies upon this step, and you have completely glossed over how it works. How does the client obtain the public key of the server? What stops an evil person from calling up the client and saying “hey client, I’m the server. Here’s my public key!” And now the client is encrypting messages that can only be decrypted by the evildoer. The evildoer has the real server’s public key, so the evildoer re-encrypts the message with the real public key and sends it on. Your whole system is thereby compromised. The public key cryptosystem is only secure if there is a secure key exchange mechanism. (And a reasonable question then is: if you have a secure key exchange mechanism, why not simply use it to exchange the message in the first place?)

    4) since the server needs to be certain that the message comes from that specific client then the client will encrypt his name (signature) with his private key.

    The client should encrypt a hash of the entire message as the signature, not just a part of the message. That way the server has evidence that the whole message was from the client.

    6) the client will encrypt the message with the public key from the server. client will then send that message to the server.

    This is extremely inefficient. Better is for the server and client to agree upon a key to a symmetric cryptosystem. The key can be transmitted between the server and the client using the public key cryptosystem. The server and client now have a shared secret key that they can use for this communication session.

    9) lastly, the server will decrypt the client signature with the public key that was contained on the message to verify that the message is from that client.

    How on earth does that help anything? I want to send you a message. You want to know who it comes from. So I send you a photocopy of my drivers license, so you can compare the signature on the license with the signature on the message. How do you know I sent you my drivers license and not a photocopy of someone else’s? This doesn’t solve the client authentication problem at all. Again, you need to solve the key distribution problem. The system depends on there being a secure key distribution infrastructure, which you have not specified.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I need to send and receive data over serial connections (RS-232 and RS-422). How
I need to send some data from a SQL DB Server on an internal
I need send certain attributes(say, human readable user name) from server to client after
I need to send MMS thought a C# application. I have already found 2
I need to send a very specific (non-standard) string to an FTP server: dir
I need to send a lua_state to a server using Sockets in C ++.
The situation is I have multiple webservices for which I need send request and
I need to send an apex web service some data. Then name of the
I need to send a string to server. That string is having some special
Need to send some data between managed c# and unmanaged c++. After some research

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.