Deserialize, CryptoStream, and NetworkStream

From: Mike (clarksmr_at_yahoo.com)
Date: 02/27/04


Date: Thu, 26 Feb 2004 19:11:49 -0500

I'm having trouble in C# getting (de)serialization to work over a
CryptoStream attached to a NetworkStream. The issue is that the
Deserialize() call blocks until the stream is closed, rather than just
flushed.

I'd really like to know what I'm doing wrong, so here is a short code
listing that exhibits the problem. Any insights would be greatly
appreciated.

-- Mike

Files in listing: client.cs. server.cs

//----------------------------------------------
// Begin client.cs
//----------------------------------------------
using System;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections;
using System.IO;
using System.Security.Cryptography;
using System.Threading;

class Client
{
 static void Main(string[] args)
 {
  // Initialize all the objects we need.
  TcpClient client = new TcpClient("localhost", 8000);
  NetworkStream netStream = client.GetStream();
  SymmetricAlgorithm crypt = Rijndael.Create();
  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};
  crypt.Key = Key;
  crypt.IV = IV;
  BinaryFormatter bf = new BinaryFormatter();
  CryptoStream encryptedStream = new CryptoStream(netStream,
crypt.CreateEncryptor(), CryptoStreamMode.Write);
  String m = "test";

  // Serialize a message to an encrypted network stream, then flush the
stream
  Console.WriteLine("Serializing message");
  Console.WriteLine("Message is: " + m);
  bf.Serialize(encryptedStream, m);
  Console.WriteLine("Message serialized");
  encryptedStream.FlushFinalBlock();
  encryptedStream.Flush();
  Console.WriteLine("Stream flushed");

  // At this point, the message should already have arrived at the server.
  // However, you'll notice during the next 5 seconds that the server
  // will act as though it hasn't received the message.
  Thread.Sleep(5000);
  encryptedStream.Close();
  Console.WriteLine("Stream closed");
  // Now, the server will have displayed the message. So Close() is doing
  // something to finalize sending the message that Flush() didn't do.

  // Finally, wait another 5 seconds to prove that Close() is what did it,
  // rather than destruction of some object.
  Thread.Sleep(5000);
 }
}
//----------------------------------------------
// End client.cs
//----------------------------------------------

//----------------------------------------------
// Begin server.cs
//----------------------------------------------
using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections;
using System.IO;
using System.Security.Cryptography;
using System.Threading;

class Server
{
 static void Main(string[] args)
 {
  IPAddress localHost = Dns.Resolve("localhost").AddressList[0];
  TcpListener server = new TcpListener(localHost, 8000);
  server.Start();
  TcpClient client = server.AcceptTcpClient();
  NetworkStream netStream = client.GetStream();
  SymmetricAlgorithm crypt = Rijndael.Create();
  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};
  crypt.Key = Key;
  crypt.IV = IV;
  BinaryFormatter bf = new BinaryFormatter();
  CryptoStream encryptedStream = new CryptoStream(netStream,
crypt.CreateDecryptor(), CryptoStreamMode.Read);

  Console.WriteLine("Deserializing message");
  String m = (String) bf.Deserialize(encryptedStream);
  Console.WriteLine("Message deserialized");
  Console.WriteLine("Message was: " + m);
 }
}
//----------------------------------------------
// End server.cs
//----------------------------------------------



Relevant Pages

  • Deserialize, CryptoStream, and NetworkStream
    ... CryptoStream attached to a NetworkStream. ... BinaryFormatter bf = new BinaryFormatter; ... the server will have displayed the message. ...
    (microsoft.public.dotnet.framework.remoting)
  • Re: Network and Cyrpto Stream help
    ... If the server uses the CryptoStream and the client only uses NetworkStream, ...
    (microsoft.public.dotnet.framework)
  • Re: CryptoStream problem
    ... >>I've a server which listen to a port, and then Readfrom it, and a ... >>My NetworkStream is wrapped in a CryptoStream, and my problem is that I ... >>CryptoStream, ...
    (microsoft.public.dotnet.framework)
  • NNTP Client
    ... the problem is the machine keep stuck (probbley beacuse it ain't gettin` data from the server) after the user name sent to the server when it's try to read the stream, i checked it out in telnet and server send stream after i send the user name any idea why it's not workin`? ... Dim returndata As String ... Dim networkStream As NetworkStream = tcpClient.GetStream ...
    (microsoft.public.dotnet.languages.vb)
  • NetworkStream with CryptoStream help
    ... If the server sends data using networkStream, ... If the client buffer is small the server sends the message. ... Stream write = new CryptoStream, ...
    (microsoft.public.dotnet.framework)