decryption error: Padding is invalid and cannot be removed

62 Views Asked by At

My program works fine until aes encoding is added.

I sent the key and IV from the server side and the client side received it.

But when running the program after the client connects to the server, the server immediately notices Client disconnected: Padding is invalid and cannot be removed.

I have tried many ways and determined that it is an error that occurred during decryption

This is code in client side:

    static void Main(string[] args)
    {
        Console.WriteLine("Connecting to server...");
        TcpClient client = new TcpClient("localhost", 8888);
        Console.WriteLine("Connected to server!");

        NetworkStream stream = client.GetStream();

        // Receive the shared key and IV from the server
        key = new byte[32];
        stream.Read(key, 0, key.Length);

        iv = new byte[16];
        stream.Read(iv, 0, iv.Length);

        Console.WriteLine("Secret key: " + Convert.ToBase64String(key));
        Console.WriteLine("Secret IV: " + Convert.ToBase64String(iv));

        // Start a new thread to read messages from the server
        Thread t = new Thread(new ParameterizedThreadStart(ReadMessages));
        t.Start(stream);

        while (true)
        {
            // Read input from the user
            Console.Write("> ");
            string message = Console.ReadLine();
            byte[] messageBytes = Encoding.UTF8.GetBytes(message);
            byte[] encrypted = AesEncrypt(messageBytes, key, iv);

            // Send the message to the server
            stream.Write(encrypted, 0, encrypted.Length);
        }
    }

    static void ReadMessages(object obj)
    {
        NetworkStream stream = (NetworkStream)obj;
        byte[] buffer = new byte[1024];

        while (true)
        {
            try
            {
                // Read the incoming message from the server
                int bytesRead = stream.Read(buffer, 0, buffer.Length);
                byte[] decrypted = AesDecrypt(buffer, key, iv);
                string message = Encoding.UTF8.GetString(decrypted);

                Console.WriteLine("Message received: " + message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Server disconnected: " + ex.Message);
                break;
            }
        }
    }

This is code in server side:

static void Main(string[] args)
        {
            Console.WriteLine("Starting server...");
            server = new TcpListener(IPAddress.Any, 8888);
            server.Start();
        aes = new AesManaged();
        key = aes.Key;
        iv = aes.IV;

        Console.WriteLine("Secret key: " + Convert.ToBase64String(key));
        Console.WriteLine("Secret IV: " + Convert.ToBase64String(iv));


        while (true)
        {
            Console.WriteLine("Waiting for client...");
            TcpClient client = server.AcceptTcpClient();
            Console.WriteLine("Client connected!");

            // Add the client to the list
            clients.Add(client);

            // Start a new thread to handle the client
            Thread t = new Thread(new ParameterizedThreadStart(HandleClient));
            t.Start(client);
        }
    }

    static void HandleClient(object obj)
    {
        TcpClient client = (TcpClient)obj;
        NetworkStream stream = client.GetStream();
        // Send the shared key and IV to the client
        stream.Write(key, 0, key.Length);
        stream.Write(iv, 0, iv.Length);
        while (true)
        {
            try
            {
                byte[] buffer = new byte[1024];
                int bytesRead = stream.Read(buffer, 0, buffer.Length);
                byte[] decryptedBytes = AesDecrypt(buffer, key, iv);
                string message = Encoding.UTF8.GetString(decryptedBytes, 0, decryptedBytes.Length);
                BroadcastMessage(message);
                Console.WriteLine("Message received: " + message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Client disconnected: " + ex.Message);
                clients.Remove(client);
                client.Close();
                return;
            }
        }
    }

    static void BroadcastMessage(string message)
    {
        foreach (TcpClient client in clients)
        {
            NetworkStream stream = client.GetStream();
            byte[] messageBytes = Encoding.UTF8.GetBytes(message);
            byte[] encryptedBytes = AesEncrypt(messageBytes, key, iv);
            stream.Write(encryptedBytes, 0, encryptedBytes.Length);
        }
    }

This is my Encryption methods

static public byte[] AesEncrypt(byte[] message, byte[] key, byte[] iv)
    {
        using (Aes aes = Aes.Create())
        {
            aes.Key = key;
            aes.IV = iv;
            ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
            byte[] encryptedMessage = encryptor.TransformFinalBlock(message, 0, message.Length);
            return encryptedMessage;
        }
    }

    static public byte[] AesDecrypt(byte[] encryptedMessage, byte[] key, byte[] iv)
    {
        using (Aes aes = Aes.Create())
        {
            aes.Key = key;
            aes.IV = iv;
            ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
            byte[] decryptedMessage = decryptor.TransformFinalBlock(encryptedMessage, 0, encryptedMessage.Length);
            return decryptedMessage;
        }
    }
0

There are 0 best solutions below