/// <summary> /// A client requested login. /// </summary> /// <param name="Client">NetworkClient instance.</param> /// <param name="Packet">ProcessedPacket instance.</param> public static void InitialClientConnect(NetworkClient Client, ProcessedPacket Packet) { Console.WriteLine("Server receives data - test 1"); PacketStream EncryptedPacket = new PacketStream(0x02, 0); EncryptedPacket.WriteHeader(); ClientPublicKey = Packet.ReadBytes((Packet.ReadByte())); AESEncryptor Enc = (AESEncryptor)Client.ClientEncryptor; Enc.NOnce = Packet.ReadBytes((Packet.ReadByte())); Enc.PublicKey = ClientPublicKey; Enc.PrivateKey = ServerPrivateKey; Client.ClientEncryptor = Enc; //THIS IS IMPORTANT - public key must be derived from private! ServerPublicKey = ServerPrivateKey.PublicKey.ToByteArray(); ChallengeResponse = new byte[16]; m_Random.GetNonZeroBytes(ChallengeResponse); MemoryStream StreamToEncrypt = new MemoryStream(); BinaryWriter Writer = new BinaryWriter(StreamToEncrypt); Writer.Write(ChallengeResponse, 0, ChallengeResponse.Length); Writer.Flush(); byte[] EncryptedData = StaticStaticDiffieHellman.Encrypt(ServerPrivateKey, ECDiffieHellmanCngPublicKey.FromByteArray(ClientPublicKey, CngKeyBlobFormat.EccPublicBlob), Enc.NOnce, StreamToEncrypt.ToArray()); EncryptedPacket.WriteUInt16((ushort)(PacketHeaders.UNENCRYPTED + (1 + ServerPublicKey.Length) + (1 + EncryptedData.Length))); EncryptedPacket.WriteByte((byte)ServerPublicKey.Length); EncryptedPacket.WriteBytes(ServerPublicKey); EncryptedPacket.WriteByte((byte)EncryptedData.Length); EncryptedPacket.WriteBytes(EncryptedData); Client.Send(EncryptedPacket.ToArray()); NetworkFacade.Listener.UpdateClient(Client); Console.WriteLine("Test 1: passed!"); }
/// <summary> /// A client requested login. /// </summary> /// <param name="Client">NetworkClient instance.</param> /// <param name="Packet">ProcessedPacket instance.</param> public static void InitialClientConnect(NetworkClient Client, ProcessedPacket Packet) { Console.WriteLine("Server receives data - test 1"); //AES is used to encrypt all further communication between client and server. AesCryptoServiceProvider AesCrypto = new AesCryptoServiceProvider(); AesCrypto.GenerateKey(); AesCrypto.GenerateIV(); AES AesEncryptor = new AES(AesCrypto.Key, AesCrypto.IV); SessionKey = AesCrypto.Key; IV = AesCrypto.IV; Guid Nonce = new Guid(Packet.ReadPascalString()); //Username would normally be used to lookup client's public key in DB (only time such a use is valid). string Username = Packet.ReadPascalString(); ECDiffieHellmanPublicKey ClientPub = StaticStaticDiffieHellman.ImportKey("ClientPublic.dat"); PacketStream EncryptedPacket = new PacketStream(0x02, 0); EncryptedPacket.WriteHeader(); MemoryStream StreamToEncrypt = new MemoryStream(); BinaryWriter Writer = new BinaryWriter(StreamToEncrypt); Writer.Write((byte)ChallengeResponse.ToByteArray().Length); Writer.Write(ChallengeResponse.ToByteArray(), 0, ChallengeResponse.ToByteArray().Length); Writer.Write((byte)SessionKey.Length); Writer.Write(SessionKey, 0, SessionKey.Length); Writer.Write((byte)IV.Length); Writer.Write(IV, 0, IV.Length); Writer.Flush(); byte[] EncryptedData = StaticStaticDiffieHellman.Encrypt(ServerKey, ClientPub, Nonce.ToByteArray(), StreamToEncrypt.ToArray()); EncryptedPacket.WriteUInt16((ushort)(PacketHeaders.UNENCRYPTED + 1 + EncryptedData.Length)); EncryptedPacket.WriteByte((byte)EncryptedData.Length); EncryptedPacket.Write(EncryptedData, 0, EncryptedData.Length); Client.Send(EncryptedPacket.ToArray()); Console.WriteLine("Test 1: passed!"); }