Связь клиент / сервер с Diff ie Hellman Key Exchange и Aes с C# - PullRequest
0 голосов
/ 04 февраля 2020

Мне нужны две программы для связи друг с другом, и связь должна быть зашифрована с помощью aes, мне нужно сделать это с помощью обмена ключами diff ie hellman. У меня есть класс DiffieHellman для генерации ключей и с методами шифрования, дешифрования и двумя консольными приложениями с именем alice и bob, когда я запускаю приложения, возникает много исключений. Это мой первый раз, когда я использую криптографию и сокеты, поэтому я не понимаю, как они работают, может кто-нибудь сказать мне, что я делаю неправильно и как я могу это исправить?

public class DiffieHellman
{
        private Aes aes = null;
        private ECDiffieHellmanCng diffieHellman = null;
        private readonly byte[] publicKey;

    public DiffieHellman()
    {
        this.aes = new AesCryptoServiceProvider();

        this.diffieHellman = new ECDiffieHellmanCng
        {
            KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash,
            HashAlgorithm = CngAlgorithm.Sha256
        };

        // This is the public key we will send to the other party
        this.publicKey = this.diffieHellman.PublicKey.ToByteArray();
    }

    public byte[] PublicKey
    {
        get
        {
            return this.publicKey;
        }
    }

    public byte[] IV
    {
        get
        {
            return this.aes.IV;
        }
    }

    public byte[] Encrypt(byte[] publicKey, string secretMessage)
    {
        byte[] encryptedMessage;
        var key = CngKey.Import(publicKey, CngKeyBlobFormat.EccPublicBlob);
        var derivedKey = this.diffieHellman.DeriveKeyMaterial(key); // "Common secret"

        this.aes.Key = derivedKey;

        using (var cipherText = new MemoryStream())
        {
            using (var encryptor = this.aes.CreateEncryptor())
            {
                using (var cryptoStream = new CryptoStream(cipherText, encryptor, CryptoStreamMode.Write))
                {
                    byte[] ciphertextMessage = Encoding.UTF8.GetBytes(secretMessage);
                    cryptoStream.Write(ciphertextMessage, 0, ciphertextMessage.Length);
                }
            }

            encryptedMessage = cipherText.ToArray();
        }

        return encryptedMessage;
    }

    public string Decrypt(byte[] publicKey, byte[] encryptedMessage, byte[] iv)
    {
        string decryptedMessage;
        var key = CngKey.Import(publicKey, CngKeyBlobFormat.EccPublicBlob);
        var derivedKey = this.diffieHellman.DeriveKeyMaterial(key);

        this.aes.Key = derivedKey;
        this.aes.IV = iv;

        using (var plainText = new MemoryStream())
        {
            using (var decryptor = this.aes.CreateDecryptor())
            {
                using (var cryptoStream = new CryptoStream(plainText, decryptor, CryptoStreamMode.Write))
                {
                    cryptoStream.Write(encryptedMessage, 0, encryptedMessage.Length);
                }
            }

            decryptedMessage = Encoding.UTF8.GetString(plainText.ToArray());
        }

        return decryptedMessage;
    }
}  


  class Alice
  {
      static void Main(string[] args)
      {

        DiffieHellman dhke = new DiffieHellman();

        while (true)
        {
            TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 13000);
            server.Start();

            Socket s = server.AcceptSocket();

            byte[] encryptedText = new byte[1024];
            int k = s.Receive(encryptedText);
            Console.Write("Friend: ");

            byte[] bobPublicKey = new byte[1024];
            s.Receive(bobPublicKey);

            Console.WriteLine(dhke.Decrypt(bobPublicKey,encryptedText,dhke.IV));

            Console.WriteLine();

            ASCIIEncoding asen = new ASCIIEncoding();
            string message = Console.ReadLine();

            s.Send(dhke.Encrypt(dhke.PublicKey,message));

            s.Close();
            server.Stop();
        }
    }
}


class Bob
{
    static void Main(string[] args)
    {

        DiffieHellman dhke = new DiffieHellman();

        while (true)
        {
            TcpClient tcpClient = new TcpClient();

            tcpClient.Connect("127.0.0.1", 13000);

            String message = Console.ReadLine();
            Stream clientStream = tcpClient.GetStream();

            ASCIIEncoding asen = new ASCIIEncoding();
            byte[] messageBuffer = new byte[1024];
            messageBuffer = dhke.Encrypt(dhke.PublicKey, message);

            clientStream.Write(messageBuffer, 0, messageBuffer.Length);
            clientStream.Write(dhke.PublicKey, 0, dhke.PublicKey.Length);

            byte[] encryptedText = new byte[1024];
            int k = clientStream.Read(encryptedText, 0, encryptedText.Length);

            Console.Write("Friend: ");
            byte[] alicePublicKey = new byte[1024];
            clientStream.Read(alicePublicKey, 0, alicePublicKey.Length);

            Console.WriteLine(dhke.Decrypt(alicePublicKey,encryptedText,dhke.IV));

            Console.WriteLine();
            tcpClient.Close();
        }
    }
}

1 Ответ

0 голосов
/ 07 февраля 2020

Я исправил многие вещи до сих пор, обмен ключами diff ie hellman в порядке и шифрование / дешифрование с помощью aes, у меня все еще есть ошибка, когда я отправляю текст и дешифрую его в другой программе, тогда он показывает некоторые другие символы шифрования с расшифрованным текстом. Длина IV составляет 16 байт, и я устанавливаю длину сообщения равной 32 байтам, когда я отправляю текст размером меньше или равным 16 символам, он испорчен, а когда я отправляю текст размером больше 16 символов, он работает нормально. enter image description here

class DiffieHellman
{
    private Aes aes = null;
    private ECDiffieHellmanCng diffieHellman = null;
    private readonly byte[] publicKey;

    public DiffieHellman()
    {
        this.aes = new AesCryptoServiceProvider();

        this.diffieHellman = new ECDiffieHellmanCng
        {
            KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash,
            HashAlgorithm = CngAlgorithm.Sha256
        };

        // This is the public key we will send to the other party
        this.publicKey = this.diffieHellman.PublicKey.ToByteArray();
    }

    public byte[] PublicKey
    {
        get
        {
            return this.publicKey;
        }
    }

    public byte[] IV
    {
        get
        {
            return this.aes.IV;
        }
    }

    public byte[] Encrypt(byte[] publicKey, string secretMessage)
    {
        byte[] encryptedMessage;
        var key = CngKey.Import(publicKey, CngKeyBlobFormat.EccPublicBlob);
        var derivedKey = this.diffieHellman.DeriveKeyMaterial(key); // "Common secret"

        this.aes.Key = derivedKey;
        this.aes.Padding = PaddingMode.Zeros;

        using (var cipherText = new MemoryStream())
        {
            using (var encryptor = this.aes.CreateEncryptor())
            {
                using (var cryptoStream = new CryptoStream(cipherText, encryptor, CryptoStreamMode.Write))
                {
                    byte[] ciphertextMessage = Encoding.UTF8.GetBytes(secretMessage);
                    cryptoStream.Write(ciphertextMessage, 0, ciphertextMessage.Length);
                }
            }

            encryptedMessage = cipherText.ToArray();
        }

        return encryptedMessage;
    }

    public string Decrypt(byte[] publicKey, byte[] encryptedMessage, byte[] iv)
    {
        string decryptedMessage;
        var key = CngKey.Import(publicKey, CngKeyBlobFormat.EccPublicBlob);
        var derivedKey = this.diffieHellman.DeriveKeyMaterial(key);

        this.aes.Key = derivedKey;
        this.aes.IV = iv;
        this.aes.Padding = PaddingMode.Zeros;

        using (var plainText = new MemoryStream())
        {
            using (var decryptor = this.aes.CreateDecryptor())
            {
                using (var cryptoStream = new CryptoStream(plainText, decryptor, CryptoStreamMode.Write))
                {
                    cryptoStream.Write(encryptedMessage, 0, encryptedMessage.Length);
                }
            }

            decryptedMessage = Encoding.UTF8.GetString(plainText.ToArray());
        }

        return decryptedMessage;
    }
}

class Alice
{
    static void Main(string[] args)
    {

        while (true)
        {
            DiffieHellman dhke = new DiffieHellman();
            ASCIIEncoding asen = new ASCIIEncoding();
            TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 13000);
            server.Start();

            Socket s = server.AcceptSocket();

            byte[] bobPublicKey = new byte[140];
            byte[] bobIV = new byte[16];

            s.Send(dhke.PublicKey);

            s.Receive(bobPublicKey);

            s.Receive(bobIV);

            byte[] acceptedMessage = new byte[32];

            s.Receive(acceptedMessage);

            System.Threading.Thread.Sleep(1000);
            Console.WriteLine("Mesazhi qe vjen i enkriptuar " + asen.GetString(acceptedMessage));
            Console.WriteLine();
            string decryptedMessage = dhke.Decrypt(bobPublicKey, acceptedMessage, bobIV);
            Console.ForegroundColor = ConsoleColor.Green;
            Console.Write("Friend: ");
            Console.WriteLine(decryptedMessage);
            Console.WriteLine();
            Console.ForegroundColor = ConsoleColor.Red;

            string mesazhi = Console.ReadLine();
            byte[] encryptedMessage = dhke.Encrypt(bobPublicKey, mesazhi);
            Console.ResetColor();
            Console.WriteLine();
            Console.WriteLine("Mesazhi qe dergohet i enkriptuar " + asen.GetString(encryptedMessage));
            Console.WriteLine();

            s.Send(encryptedMessage);

            s.Send(dhke.IV);

            s.Close();
            server.Stop();
        }
    }
}

class Bob
{
    static void Main(string[] args)
    {
        while (true)
        {
            DiffieHellman dhke = new DiffieHellman();
            ASCIIEncoding asen = new ASCIIEncoding();
            TcpClient tcpClient = new TcpClient();
            tcpClient.Connect("127.0.0.1", 13000);
            Stream stream = tcpClient.GetStream();
            byte[] alicePublicKey = new byte[140];

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

            stream.Write(dhke.PublicKey, 0, dhke.PublicKey.Length);

            stream.Write(dhke.IV, 0, dhke.IV.Length);

            Console.ForegroundColor = ConsoleColor.Red;
            String message = Console.ReadLine();  //Shkruaj mesazhin
            byte[] encryptedMessage = dhke.Encrypt(alicePublicKey, message);
            Console.ResetColor();
            Console.WriteLine();
            Console.WriteLine("Mesazhi qe dergohet i enkriptuar " + asen.GetString(encryptedMessage));
            Console.WriteLine();

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

            byte[] acceptedMessage = new byte[32];

            byte[] aliceIV = new byte[16];

            stream.Read(acceptedMessage, 0, acceptedMessage.Length);
            stream.Read(aliceIV, 0, aliceIV.Length);

            Console.WriteLine("Mesazhi qe vjen i enkriptuar " + asen.GetString(acceptedMessage));
            Console.WriteLine();
            string decryptedMessage = dhke.Decrypt(alicePublicKey, acceptedMessage, aliceIV);
            Console.ForegroundColor = ConsoleColor.Green;
            System.Threading.Thread.Sleep(1000);
            Console.Write("Friend: ");
            Console.WriteLine(decryptedMessage);
            Console.WriteLine();
            tcpClient.Close();
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...