Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
客户机/服务器与Diffie-Hellman密钥交换通信,Aes与C#_C#_Sockets_Aes_Diffie Hellman - Fatal编程技术网

客户机/服务器与Diffie-Hellman密钥交换通信,Aes与C#

客户机/服务器与Diffie-Hellman密钥交换通信,Aes与C#,c#,sockets,aes,diffie-hellman,C#,Sockets,Aes,Diffie Hellman,我需要两个程序与另一个进行通信,通信应该用aes加密,我需要用diffie-hellman密钥交换进行加密。我使用DiffieHellman类生成密钥,使用encrypt、decrypt方法和两个名为alice和bob的控制台应用程序,当我运行这些应用程序时,会抛出许多异常。这是我第一次使用密码和套接字,所以我不明白它们是如何工作的,有人能告诉我我做错了什么,我如何修复它吗 public class DiffieHellman { private Aes aes = null;

我需要两个程序与另一个进行通信,通信应该用aes加密,我需要用diffie-hellman密钥交换进行加密。我使用DiffieHellman类生成密钥,使用encrypt、decrypt方法和两个名为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();
        }
    }
}

到目前为止,我修复了很多问题,diffie-hellman密钥交换很好,使用aes加密/解密,我仍然有一个错误,当我发送文本并在另一个程序中解密时,它会显示一些其他加密字符和解密文本。IV长度为16字节,我将消息长度设置为32字节,当我发送小于或等于16个字符的文本时,它会出错,当我发送大于16个字符的文本时,它会正常工作。


你考虑过使用SSL流并设置密码吗?@RowTransmish这是我大学的一项作业,我必须使用diffie hellman作为密钥,使用任何对称算法进行加密和解密。你有什么例外?它们对你意味着什么?你已经试着改变了什么,但无法开始工作?@bartonjs我发布了一个答案,直到现在我已经解决了这个问题,我没有任何例外,只是一个逻辑问题
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();
        }
    }
}