客户端/服务器,加密通信

时间:2012-04-02 23:27:55

标签: c# encryption client-server

我在c#中有一个基本的tcp客户端/服务器设置。我现在正在尝试加密来回传输的数据。我能够将数据从客户端发送到服务器,让服务器运行命令,然后尝试将结果发送回客户端。我可以从客户端获取数据到服务器,服务器运行命令。当服务器尝试将结果发送回客户端时,我在客户端上收到一条错误消息,表明该流不可读。以下是相关的代码部分。

服务器:

    .......
//Create an instance of TcpListener to listen for TCP connection.
    TcpListener tcpListener = new TcpListener(IPAddress.Any, TcpPort);
    try
    {
        while (true)
        {
            tcpListener.Start();
            //Accept the client if one is found.
            TcpClient TCP = tcpListener.AcceptTcpClient();
           // Console.WriteLine("Client connected through TCP.");

            //Create a network stream from the connection.
            NetworkStream NetStream = TCP.GetStream();

            //Create a new instance of the RijndaelManaged class
            // and decrypt the stream.
            RijndaelManaged RMCrypto = new RijndaelManaged();


            //Create a CryptoStream, pass it the NetworkStream,  decrypt with the Rijndael class using the key and IV.
            CryptoStream CryptStream = new CryptoStream(NetStream,RMCrypto.CreateDecryptor(Key, IV),CryptoStreamMode.Read);

            //Read the stream.
            StreamReader SReader = new StreamReader(CryptStream);

            //run the command received
            string commandToRun = SReader.ReadToEnd();
            string commandOutput = runCommand(commandToRun);
            Console.WriteLine("output is " + commandOutput);
       //     SReader.Close();

            // now send results back
            CryptoStream CStream_WRITE = new CryptoStream(NetStream, RMCrypto.CreateEncryptor(Key, IV), CryptoStreamMode.Write);

            if (CStream_WRITE.CanWrite)
            {
                //Create a StreamWriter for easy writing to the network stream.
                StreamWriter SWriter2 = new StreamWriter(CStream_WRITE);

                //Write to the stream.
                SWriter2.Write(commandOutput, commandOutput.Length);
                Console.WriteLine("writing {0} bytes back ", commandOutput.Length);
                SWriter2.Flush();
                SWriter2.Close();
            }

       //       CStream_WRITE.Close();
      //        NetStream.Close();
      //        TCP.Close();
                tcpListener.Stop();

        } // end while
    }
    //Catch any exceptions. 
    catch
    {
        Console.WriteLine("Server Failed");
    }
}

这是客户端:.......粗线是我收到错误的地方

        //Create a TCP connection to a listening TCP process.

        TcpClient TCP = new TcpClient(serverName, TCPPORT);

        //Create a network stream from the TCP connection. 
        NetworkStream NetStream = TCP.GetStream();

        //Create a new instance of the RijndaelManaged class
        // and encrypt the stream.
        RijndaelManaged RMCrypto = new RijndaelManaged();

        byte[] Key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
        byte[] IV = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };

        //Create a CryptoStream, pass it the NetworkStream, and encrypt 
        //it with the Rijndael class.
        CryptoStream CryptStream = new CryptoStream(NetStream, RMCrypto.CreateEncryptor(Key, IV), CryptoStreamMode.Write);

        if (CryptStream.CanWrite)
        {
            //Create a StreamWriter for easy writing to the network stream.
            StreamWriter SWriter = new StreamWriter(CryptStream);

            //Write to the stream.
            SWriter.WriteLine(theData);
            SWriter.Flush();
            SWriter.Close();
      //    CryptStream.Close();

            //Inform the user that the message was written to the stream.
            Console.WriteLine("The message was sent.");
        }

        // get response
        **CryptoStream CStreamREAD = new CryptoStream(NetStream, RMCrypto.CreateDecryptor(Key, IV), CryptoStreamMode.Read);**
        if (CStreamREAD.CanRead)
        {
            Console.WriteLine("stream can read\n");
            StreamReader SReader = new StreamReader(CStreamREAD);
            string commandResults = SReader.ReadToEnd();
            Console.WriteLine("receiving {0} bytes from server", commandResults.Length);
            Console.WriteLine("results are " + commandResults)

2 个答案:

答案 0 :(得分:4)

最安全的BY FAR是实现已有的协议,如SSL。您可以使用SslStream类来提供安全性和服务器身份验证,或者您可以切换到WCF而不处理流。 Here是关于如何为WCF启用SSL的问题。至于一个基本的WCF教程,有数百个。

滚动自己可能非常不安全且容易出错。

答案 1 :(得分:0)

StreamWriter.close()还会关闭基础流,关闭CryptoStream,根据API关闭底层套接字。

至少,这是我作为经验丰富的Java开发人员的猜测:)