Listing B
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 TCP server (synchronous) to show .NET symmetric and
       /// asymmetric encryption features.
       /// </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:
       /// >cryptoserver [port] [secret message]
       /// The secret message is what will be encrypted and sent to the
       /// client. If you put whitespace in the secret message as
       /// a command-line arg, be sure to enclose it in quotes.
       ///
       /// Steps:
       /// * Open TCP Port,listen, accept client
       /// * Wait for 252 byte serialization of client's RSA public key
       /// * Use that to encrypt a TripleDES Key and IV
       /// * Send those back to the client
       /// * Use the TripleDES Key and IV to encrypt the secret message
       /// * Send secret message to client.
       /// </remarks>

      public class CryptoServer
       {
             
              private const string USAGE = "USAGE:\n"
                                         + "cryptoserver [port] [secret message]\n\n"
                                        + "If secret message has whitespace, "
                                            + "enclose in quotes.";
             
             private const int RSA_KEY_SIZE_BITS                   = 1024;
              private const int RSA_KEY_SIZE_BYTES            = 252;
              private const int TDES_KEY_SIZE_BITS            = 192;
             
              public static void Main(string[] args)
              {
                     int    port;
                     string        msg;
                    
                     TcpListener   listener;
                     TcpClient     client;
                     SymmetricAlgorithm   symm;
                     RSACryptoServiceProvider          rsa;
                    
                     if (args.Length!=2)
                     {
                           Console.WriteLine(USAGE);
                           return;
                     }
                     try
                     {
                           port = Int32.Parse(args[0]);
                           msg = args[1];
                     }
                     catch
                     {
                           Console.WriteLine(USAGE);
                           return;
                     }
                    
                     try
                     {
                           listener = new TcpListener(port);
                           listener.Start();
                           Console.WriteLine("Listening on port {0}...",port);
                    
                          
                           client = listener.AcceptTcpClient();
                           Console.WriteLine("connection....");
                     }
                     catch (Exception e)
                     {
                           Console.WriteLine(e.Message);
                           Console.WriteLine(e.StackTrace);
                           return;
                     }
                    
                     try
                     {                         
                           rsa = new RSACryptoServiceProvider();
                           rsa.KeySize = RSA_KEY_SIZE_BITS;
                          
                           // Set the client public key
                           rsa.ImportParameters(getClientPublicKey(client));
                          
                           symm = new TripleDESCryptoServiceProvider();
                           symm.KeySize = TDES_KEY_SIZE_BITS;
                          
                           // encrypt the Symmetric Key info using
                           // client's RSA public key, and send it to client
                          encryptAndSendSymmetricKey(client, rsa, symm);
                          
                          // Encrypt the secret message using the
                           // symmetric key, and send it
                           encryptAndSendSecretMessage(client, symm, msg);
                     }
                     catch (Exception e)
                     {
                           Console.WriteLine(e.Message);
                           Console.WriteLine(e.StackTrace);
                     }
                     finally
                     {
                           // Try to clean up. put in try...catch just
                           // in case some of these things never opened
                           try
                           {
                                  client.Close();
                                  listener.Stop();
                           }
                           catch
                           {
                                  // Ignore
                           }
                           Console.WriteLine("Server exiting...");
                     }
              } // end Main
             
              private static RSAParameters getClientPublicKey(TcpClient client)
              {
                     // Get the serialized public key from the byte stream.
                     // Deserialize it into its class instance
                     // We know it's 252 bytes (hard-coded! not robust!)
                    
                     byte[] buffer                     = new byte[RSA_KEY_SIZE_BYTES];
                     NetworkStream ns          = client.GetStream();
                    MemoryStream ms           = new MemoryStream();
                    BinaryFormatter bf = new BinaryFormatter();
                    RSAParameters result;
                    
                     int len                    = 0;
                     int totalLen  = 0;
                    
                    while(totalLen<RSA_KEY_SIZE_BYTES &&
                          (len = ns.Read(buffer,0,buffer.Length))>0)
                     {
                           totalLen+=len;
                           ms.Write(buffer, 0, len);
                     }
                    
                     ms.Position=0; // reposition so binary formatter can read all of it
                                        
                     result = (RSAParameters)bf.Deserialize(ms);
                     ms.Close();
                    
                     return result;
                    
              } // end getClientPublicKey
             
              private static void encryptAndSendSymmetricKey(
                                         TcpClient client,
                                         RSACryptoServiceProvider rsa,
                                         SymmetricAlgorithm symm)
              {
                     // Using client's public key, encrypt the
                     // symmetric key we'll be using for subsequent
                     // messages and send to client.
                     byte[] symKeyEncrypted;
                     byte[] symIVEncrypted;
                    
                     NetworkStream ns = client.GetStream();
                    
                     symKeyEncrypted = rsa.Encrypt(symm.Key, false);
                     symIVEncrypted = rsa.Encrypt(symm.IV, false);
                    
                     ns.Write(symKeyEncrypted, 0, symKeyEncrypted.Length);
                     ns.Write(symIVEncrypted, 0, symIVEncrypted.Length);                 
                    
              } // end encryptAndSendSymmetricKey

      
             private static void encryptAndSendSecretMessage(
                                         TcpClient client,
                                         SymmetricAlgorithm symm,
                                         string secretMsg)
             
              {
                     // Using the symmetric key and initialization vector,
                     // Eencrypt the secret message and send to client.
                     byte[] msgAsBytes;
                     NetworkStream ns = client.GetStream();
                     ICryptoTransform transform =
                           symm.CreateEncryptor(symm.Key,symm.IV);
                     CryptoStream cstream =
                           new CryptoStream(ns, transform, CryptoStreamMode.Write);
                    
                     // First get the secretMsg into bytes
                     msgAsBytes = Encoding.ASCII.GetBytes(secretMsg);
                    
                     cstream.Write(msgAsBytes, 0, msgAsBytes.Length);
                     cstream.FlushFinalBlock();              
                    
              } // end encryptAndSendSecretMessage
             
       }// end class CryptoServer
      
}// end namespace