2 using System.Collections.Generic;
4 using System.Security.Cryptography;
15 private enum ClientState
21 private class AdditionalData
24 public ClientState ClientState = ClientState.Initial;
27 private Dictionary<ClientData, AdditionalData> additionalData;
28 private RSACryptoServiceProvider rsa;
29 private string privateKey, publicKey;
41 additionalData =
new Dictionary<ClientData, AdditionalData>();
43 privateKey = HelperFunctions.ToXmlString(rsa,
true);
44 publicKey = HelperFunctions.ToXmlString(rsa,
false);
47 #region Public Methods 50 #region Private Methods 51 private byte[] EncryptBytes(
byte[] clientKey,
byte[] bytesToBeEncrypted)
53 byte[] encryptedBytes =
null;
57 byte[] saltBytes =
new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
59 using (MemoryStream ms =
new MemoryStream())
61 using (RijndaelManaged AES =
new RijndaelManaged())
66 AES.Mode = CipherMode.CBC;
68 var key =
new Rfc2898DeriveBytes(clientKey, saltBytes, 1000);
69 AES.Key = key.GetBytes(AES.KeySize / 8);
70 AES.IV = key.GetBytes(AES.BlockSize / 8);
74 using (var cs =
new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
76 cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length);
79 encryptedBytes = ms.ToArray();
83 return encryptedBytes;
86 private byte[] DecryptBytes(
byte[] clientKey,
byte[] bytesToBeDecrypted)
88 byte[] decryptedBytes =
null;
92 byte[] saltBytes =
new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
94 using (MemoryStream ms =
new MemoryStream())
96 using (RijndaelManaged AES =
new RijndaelManaged())
101 AES.Mode = CipherMode.CBC;
103 var key =
new Rfc2898DeriveBytes(clientKey, saltBytes, 1000);
104 AES.Key = key.GetBytes(AES.KeySize / 8);
105 AES.IV = key.GetBytes(AES.BlockSize / 8);
109 using (var cs =
new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
111 cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length);
114 decryptedBytes = ms.ToArray();
118 return decryptedBytes;
121 #region Handler Implementation 128 additionalData.Remove(client);
137 additionalData.Add(client,
new AdditionalData());
148 if (additionalData[client].ClientState == ClientState.Initial || additionalData[client].ClientState == ClientState.Negotiating)
150 string asciiMessage = ASCIIEncoding.ASCII.GetString(message.MessageBytes);
151 if (asciiMessage == CommunicationPrimitives.RequestPublicKey)
153 server.
QueueMessage(client, ASCIIEncoding.ASCII.GetBytes(CommunicationPrimitives.SendPublicKey +
":" + publicKey));
154 additionalData[client].ClientState = ClientState.Negotiating;
157 else if (asciiMessage.Contains(CommunicationPrimitives.SendEncryptionKey))
159 byte[] encryptedKey =
new byte[message.MessageLength - CommunicationPrimitives.SendEncryptionKey.Length - 1];
160 Array.Copy(message.MessageBytes, CommunicationPrimitives.SendEncryptionKey.Length + 1, encryptedKey, 0, encryptedKey.Length);
161 byte[] decryptedKey = rsa.Decrypt(encryptedKey,
false);
162 additionalData[client].Key = decryptedKey;
163 server.
QueueMessage(client, ASCIIEncoding.ASCII.GetBytes(CommunicationPrimitives.AcceptEncryptionKey));
164 additionalData[client].ClientState = ClientState.Encrypted;
185 if (additionalData[client].ClientState == ClientState.Encrypted)
190 byte[] encryptedBytes = message.MessageBytes;
191 byte[] decryptedBytes = DecryptBytes(additionalData[client].Key, encryptedBytes);
192 message =
new Message((uint)decryptedBytes.Length, decryptedBytes);
218 if (additionalData[client].ClientState == ClientState.Encrypted)
220 message = CommunicationPrimitives.BuildMessage(EncryptBytes(additionalData[client].Key, message.MessageBytes));
Interface for communication handlers.
bool PreHandleReceivedMessage(Server server, ClientData client, ref Message message)
Called before the message handling. Perform here any processing of the message.
Structure containing client information.
Handler that encrypts the communication.
void QueueMessage(ClientData target, byte[] message)
Queues a message to be sent.
void ClientRemoved(Server server, ClientData client)
Handles the removal of a client from the server.
void Tick(Server server)
Method performs regular operations onto the server.
bool HandleReceivedMessage(Server server, ClientData client, Message message)
Handles the received message.
Basic server class to handle TCP connections.
bool HandleClient(Server server, ClientData client)
Handles a new client.
bool HandleSendMessage(Server server, ClientData client, ref Message message)
Handles a message before sending.
EncryptionHandler(RSACryptoServiceProvider rsa)
Creates an instance of EncryptionHandler.