Listing C
using System;
using System.Text;
using System.IO;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security.Cryptography;


namespace com.billdawson.crypto
{
      
       /// <summary>
       /// Test client for showing .NET crypto over sockets.
       /// </summary>
       /// <remarks>
       /// Please note that this is a highly contrived, artificial
       /// and not robust sockets application. For example, the server
      /// assumes that the client sends all the right stuff in the
      /// right order, one after the other, without any error checks.
      ///
       ///
       /// Usage:
       /// >cryptoclient [host] [port]
       ///
       /// Steps:
       /// * Connect to host and port
       /// * Immediately send public RSA key
       /// * Receive in succession:
       /// *    Encrypted Symmetric Key and IV
       /// *    Encrypted secret message
       /// * Decrypt secret message and display
       /// </remarks>
       public class CryptoClient 
       {
              private const string USAGE = "USAGE:\n"
                                         + "cryptoclient [host] [port]";
             
              private const int RSA_KEY_SIZE_BITS                   = 1024;
              private const int RSA_KEY_SIZE_BYTES            = 252;
              private const int TDES_KEY_SIZE_BITS            = 192;
              private const int TDES_KEY_SIZE_BYTES           = 128;
              private const int TDES_IV_SIZE_BYTES            = 128;
              public static void Main(string[] args)
              {
                     int port;
                     string host;
                     TcpClient client;
                     SymmetricAlgorithm symm;
                     RSACryptoServiceProvider rsa;
                    
                     if (args.Length!=2)
                     {
                           Console.WriteLine(USAGE);
                           return;
                     }
                    
                     try // parsing arguments
                     {
                           host = args[0];
                           port = Int32.Parse(args[1]);     
                     }
                     catch
                     {
                           Console.WriteLine(USAGE);
                           return;
                     }
                    
                     try // connecting
                     {
                           client = new TcpClient();
                           client.Connect(host,port);
                    }
                     catch(Exception e)
                     {
                           Console.WriteLine(e.Message);
                           Console.Write(e.StackTrace);
                           return;
                     }
                    
                     try // everything else
                     {
                           Console.WriteLine("Connected. Sending public key.");
                           rsa = new RSACryptoServiceProvider();
                           rsa.KeySize = RSA_KEY_SIZE_BITS;
                           sendPublicKey(rsa.ExportParameters(false),client);
                           symm = new TripleDESCryptoServiceProvider();
                           symm.KeySize = TDES_KEY_SIZE_BITS;
                          
                           MemoryStream ms = getRestOfMessage(client);
                           extractSymmetricKeyInfo(rsa, symm, ms);                     
                          showSecretMessage(symm, ms);                         
                     }
                     catch(Exception e)
                     {
                           Console.WriteLine(e.Message);
                           Console.Write(e.StackTrace);
                     }
                     finally
                     {
                           try
                           {
                                 client.Close();
                           }
                           catch { // ignore
                           }
                     }
              } // end Main
             
              private static void sendPublicKey(
                                  RSAParameters key,
                                  TcpClient client)
              {
                     NetworkStream ns = client.GetStream();
                     BinaryFormatter bf = new BinaryFormatter();
                     bf.Serialize(ns,key);
              } // end sendPublicKey


             private static MemoryStream getRestOfMessage(TcpClient client)
              {
                     // This ends up getting the symmetric key,
                     // the symmetric IV, and the secret message, all encrypted.
                     // The symmetric key is encrypted with this client's
                     // public RSA key. The secret message is encrypted
                     // with the symmetric key.
                     MemoryStream ms      = new MemoryStream();                  
                    NetworkStream ns     = client.GetStream();
                     byte[] buffer              = new byte[1024];
                    
                     int len=0;

             
                    // Put everything from the NetStream into
                     // a memory stream.
                     while((len = ns.Read(buffer, 0, buffer.Length))>0)
                     {

                          ms.Write(buffer, 0, len);
                     }
                     ms.Position = 0;
                     return ms;
              } // end getRestOfMsg
             
              private static void extractSymmetricKeyInfo(
                                  RSACryptoServiceProvider rsa,
                                  SymmetricAlgorithm symm,
                                 MemoryStream msOrig)             
             {
                     MemoryStream ms = new MemoryStream();

                     // get the TDES Key -- encrypted by host
                     // with our RSA Public Key --
                     // and decrypt using our private key.
                     byte[] buffer = new byte[TDES_KEY_SIZE_BYTES];
                    msOrig.Read(buffer,0,buffer.Length);
                    symm.Key = rsa.Decrypt(buffer,false);
                    
                    // get the TDES IV -- encrypted by host
                    // with our RSA Public Key --
                    // and decrypt using our private key.                
                    buffer = new byte[TDES_IV_SIZE_BYTES];
                     msOrig.Read(buffer, 0, buffer.Length);
                     symm.IV = rsa.Decrypt(buffer,false);
                    
              } // end extractSymmetricKeyInfo
             
              private static void showSecretMessage(
                                  SymmetricAlgorithm symm,
                                  MemoryStream msOrig)
              {
                     // Everything left in the memory stream (from its position)
                     // is an encrypted, ASCII-encoded secret message
                     byte[] buffer        = new byte[1024];
                     int len              = msOrig.Read(buffer,0,buffer.Length);
                                        
                     MemoryStream ms = new MemoryStream();
                     ICryptoTransform transform =
                                        symm.CreateDecryptor(symm.Key,symm.IV);
                     CryptoStream cstream =
                                         new CryptoStream(ms, transform, CryptoStreamMode.Write);
                     cstream.Write(buffer, 0, len);
                     cstream.FlushFinalBlock();
                    
                    // The memory stream ms now has the secret message
                    // decrypted, but as bytes. Change to a string
                    ms.Position = 0;
                     len = ms.Read(buffer,0,(int) ms.Length);
                     ms.Close();
                    
                     string msg = Encoding.ASCII.GetString(buffer,0,len);
                     Console.WriteLine("The host sent me this secret message:");
                     Console.WriteLine(msg);          


              } // end showSecretMessage
             
       } // end class CryptoClient
} // end namespace