创建对称密钥时

时间:2018-06-13 03:54:03

标签: c# forms tcp cryptography diffie-hellman

我正在做一个TCP服务器和客户端应用程序。我需要加密和解密消息,但在此之前我需要创建一个与AES算法一起使用的对称密钥。我在服务器和客户端之间使用了Diffie-Hellman公钥交换。但是,当我使用公钥作为参数时,我收到参数不正确的错误。

我使用Receive和Send在服务器和客户端之间传输数据。

static byte[] Receive(NetworkStream netStream)
{
    try
    {
        byte[] receive = new byte[STD_MSG_SIZE];
        int length = netStream.Read(receive, 0, receive.Length);
        string x = Convert.ToBase64String(receive, 0, length);
        return Encoding.UTF8.GetBytes(x);
    }
    catch (Exception except)
    {
        Console.WriteLine("Error at receive\n" + except.Message + "\n" + except.StackTrace);
        return null;
    }
}

static void Send(NetworkStream netStream, byte[] message)
{
    try
    {
        byte[] send = message;
        netStream.Write(send, 0, send.Length);
    }
    catch (Exception except)
    {
        Console.WriteLine("Error at send\n" + except.Message + "\n" + except.StackTrace);
    }
}

这是客户端中的代码,我生成公钥,将其发送到服务器,然后从服务器接收公钥。

TcpClient client = new TcpClient();
client.Connect(IPAddress.Parse(STD_IP), STD_PORT);

ECDiffieHellmanCng alice = new ECDiffieHellmanCng();
alice.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
alice.HashAlgorithm = CngAlgorithm.Sha256;
byte[] publicKey = alice.PublicKey.ToByteArray();

NetworkStream ns = client.GetStream();

Send(ns, publicKey);

byte[] data = Receive(ns);

textBox1.Text = Convert.ToBase64String(data);

byte[] simKey = alice.DeriveKeyMaterial(ECDiffieHellmanCngPublicKey.FromByteArray(data, CngKeyBlobFormat.EccPublicBlob));

这是Server中的代码。我在表单中使用文本框来显示公钥。

TcpListener tcpListener = new TcpListener(IPAddress.Parse(STD_IP), STD_PORT);
tcpListener.Start();

ECDiffieHellmanCng bob = new ECDiffieHellmanCng();
bob.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
bob.HashAlgorithm = CngAlgorithm.Sha256;
byte[] publicKey = bob.PublicKey.ToByteArray();

TcpClient client = tcpListener.AcceptTcpClient();
NetworkStream ns = client.GetStream();

byte[] data = Receive(ns);

textBox1.Text = Convert.ToBase64String(data);

Send(ns, publicKey);

byte[] simKey = bob.DeriveKeyMaterial(ECDiffieHellmanCngPublicKey.FromByteArray(data, CngKeyBlobFormat.EccPublicBlob));

当我评论simKey时,我从客户端和服务器中的数据中获取了这些值。

客户端的文本框:UlVOTE5VSUFBQUFBdXZXTXgzdHFUb0hZVGY0NnFyNlovVWJuRCtUMlZqMTVGZEN5RmIrYnFLRHN3WTZ5clJIemlNblAzYUJDZUpaaW5oVTN6ODFVUWZZaWNiRUNSaUR4NFNJQXBFdE5uYzl0Z1VOV01qNTllSVRaRCtOdGp2V3lIMzZWR21FdDBUSzFKUEx1UTBFZ2tXTXRFU0E1dTJWSkxoWk1FU2NKQ2tXMUhkc0hGWUQwUmFldHJ3RT0 =

服务器文本框: UlVOTE5VSUFBQUFCcWQ3TnZzK0pFQ3BydFFYK2k4T1ErN3pGNXZQSzh6S1I3UEJvUzN3VERkdFB0N05nM2tNWi9TTXkzVFRpZ0JBMmhQdlJJakhObWJ1WlZhc3ZFUTZMUnkwQVdockhMcjh6SzlSTUtsbloxWnVwcDFqMGh3cTNNK04yNXlraUNrMk51b1BVSlZVQkJXOFM4TWQ2eEp6NzQvbHNHSWY1Sy9MUUxnZEp3OUhad2pNcW85dz0 =

1 个答案:

答案 0 :(得分:0)

令我惊讶的是,只要缓冲区足够大以容纳公钥,Read方法的使用就是正确的。

问题是你然后在Receive方法中对结果进行base64编码,该方法应该只返回字节。除了弄乱你的设计 - 如果一个读取数据的方法也对它进行编码,那绝对不是最少惊喜 - 这也会使解析公钥失败。

可以为文本框添加64位编码。但只要您不需要二进制编码,就应该将其排除在外。或至少在使用前解码它。