I need to send sensitive data to the server through a TCP connection. I have researched a lot, and I understand the theoretical part. Based on what I researched, I want to do the following:
Please note that there is a server and a client: (we assume that the public keys of the client or server can be obtained by anyone)
- Client
creates his public and private key. It can encrypt with its private key and decrypt with its public key.
the server creates its public and private keys. the private key is used to decrypt messages, and the public key is used to encrypt messages. (pay attention to another way, as with the client)
the client receives the server’s public key. the client will then be able to encrypt messages with this key, and the only one that can decrypt this message will be the server’s private key.
since the server must be sure that the message is coming from this particular client, then the client will encrypt its name (signature) with its private key.
therefore, the client’s message will contain: data to be sent, client’s public key, client’s name, encrypted using the client’s private key.
the client will encrypt the public key message from the server. the client will send this message to the server.
the server decrypts the message just received with its private key.
After decrypting the message, it will contain data (information), an encrypted signature, a public key from the client.
finally, the server will decrypt the client’s signature with the public key that was contained in the message to ensure that the message is from this client.
OK, this is how asymmetric cryptography works. I also studied classes that allow you to create these key pairs using the .NET platform. The classes that I explored that allow you to create these public and private key pairs are as follows:
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 there are problems, how to use one of these classes for this with C #? I understand how the theoretical part works, but how can I do what I just described using code. I have studied some examples, but it is difficult for me to understand 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()) {
In this program, I believe that the client is Alice, and the server is Bob. I need to split this program into two parts. It’s hard for me to understand this, and if I try, most likely I will make it work. In any case, how can I split this program into server-side code and client-side code. I know how to send bytes between server and client. But I do not want it to work, not understanding what is happening. maybe you guys can show me a simpler example.
EDIT
I managed to separate the code: here is the server code (the IP address of my computer was 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;
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;
I think this is pretty safe. Each time it sends another array of bytes, sending the same information!