Archive for March, 2009

SSL in C# using SslStream

Posted in Business on March 27th, 2009 by djurek – Be the first to comment

SSL is cryptic. This tutorial will get your C# program communicating in SSL using SslStream.

Note: Please leave a comment if the code is unreadable. WordPress seems to have entirely busted preformatted text. Even if you use HTML mode.

SSL encrypts communication between two nodes (a client and server). Without going into too much detail, SSL requires that the client authenticate the server against a list of trusted providers before communicating (think VeriSign, etc.). The server can authenticate the client, but that is typically not necessary in most communication scenarios.

To learn way too much about SSL theory, see SSL in Wikipedia. Fortunately with .net, you don’t need a complete understanding to implement SSL.

Shout outs

I would like to thank the folks who finally showed me the light:

I’m basically pulling together the things that they wrote into one easy place.

Getting started

You will need to download Microsoft Visual C# Express to code this. Depending on your install directory, you can find makecert.exe in C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\Bin.

C# coding for SSL is simple but it requires some preparation. Since SSL is based on trust of certificates issued by root authorities, you will need to:

  1. Create your own root authority
  2. Create a certificate using that authority
  3. Set your client machine to trust certificates signed by the root authority you created

Making a certificate

Remember that you need to buy a certificate from a trusted root authority before your apps will work in the mainstream. This tutorial will get you working in a test environment.

Start the MMC to manage local certificates:

  1. Start > Run > type "mmc.exe" > hit enter
  2. File menu > Add/Remove Snap-in > click the Add button > Select "Certificates" > Press "Add"
  3. Select "Computer Account" > Click Next > Select "Local Computer" > Click Finish
  4. Click Close button > Click OK

Now things should look like this:

Certificates window in MMC

Fire up a command line to create certificates:

  1. Start > Run > "cmd" >hit enter
  2. cd "C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\Bin" > hit enter
  3. Replace the parameters between %’s with your own names. Make sure %root_authority_name% matches in both instances.
  4. C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\Bin>makecert -pe -n "CN=%root_authority_name%" -ss my -sr LocalMachine -a sha1 -sky signature -r %output_filename%.cer
  5. C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\Bin>makecert -pe -n "CN=%certificate_name%" -ss my -sr LocalMachine -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.1 -in "%root_authority_name%" -is MY -ir LocalMachine -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 %certificate_output_file%.cer
  6. If each of the commands reports "Success" at the end, congratulations! You now have a root authority and a signed certificate. Check in the C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\Bin folder to find the two new .cer files you just created.

Meanwhile, you should see the following changes in your console under the Personal folder (you may need to refresh):

Certificates created and added to the store

You will also notice the presence of a couple .cer files in the C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\Bin folder. One for your root authority and the other for the certificate you generated.

In this case, the "Daniel Root Authority" certificate is the root authority that issued the certificate. The "mdumps" certificate is the certificate I issued to my test server machine. For this test, my server will use the mdumps.cer file as its SSL certificate. The client machine I am using must trust the root authority to trust the certificate.

To make the client trust the root authority, copy the root authority certificate into the "Trusted Root Certification Authority" folder on the client:

Copy the root authority certificate to the trusted issuer location. This must be done on all clients that will be communicating with the server.

You will need to copy the root certificate into the trusted location of every client that will be running your server.

Writing some code

Now the coding begins.

For simplicity, you may download my sample project with the code to get this working. You will need to copy your server certificate file (.cer) into the running directory of the executable. Also, change the hostname and certificate strings to match your configuration.

Use the following namespaces for creating sockets, encrypting communications, and storing certificates:

using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

The server

When a server instantiates an SslStream object, it must link that stream to the certificate for authentication and encryption. A simple example:

// Load the server certificate
X509Certificate serverCert = new X509Certificate(certificateFilename);

// Start listening for a connection
Console.WriteLine("Server: waiting for client connection.");
listener.Start();
clientConnection = listener.AcceptTcpClient();

// Once a client connects, associate it with an SslStream
Console.WriteLine("Server: Client has connected.");
secureStream = new SslStream(clientConnection.GetStream());

// Set the server certificate
secureStream.AuthenticateAsServer(serverCert);

Please note that other methods of accessing the certificate exist outside of the filename method. In this case, the file method is the easiest.

The AuthenticateAsServer method will throw an Exception if it encounters an error.

The client

The client authenticates the server, in this case against the server’s hostname. Notice how the client does not load a certificate, instead it compares the server’s certificate with its list of trusted root authorities (that you set up in the MMC earlier):

// Connect
Console.WriteLine("Client: Connecting to server ");
client.Connect(serverHostname, serverPortNum);

// Authenticate the server
Console.WriteLine("Client: Authenticating server");
secureStream = new SslStream(client.GetStream());
secureStream.AuthenticateAsClient(serverHostname);

// Server has authenticated
Console.WriteLine("Client: Server authenticated!");

The AuthenticateAsServer method will throw an Exception if it encounters an error. It is possible to perform custom handling of the authentication on the client side, but that is beyond the scope of this article.

Sending and receiving messages

I wrote a couple simple methods that allow you to send a string of nearly any size. Note that the method first sends an integer (known size) describing the size of the message it will send:

static void SendMessage(SslStream stream, string message)
{
    byte[] messageLengthBytes = BitConverter.GetBytes(message.Length);

    // Send the size of the object
    stream.Write(messageLengthBytes);

    ASCIIEncoding encoder = new ASCIIEncoding();
    byte[] messageBytes = encoder.GetBytes(message);

    stream.Write(messageBytes);
}

static string GetMessage(SslStream stream)
{
    byte[] byteStreamSize = new byte[sizeof(int)];
    stream.Read(byteStreamSize, 0, sizeof(int));
    int streamSize = BitConverter.ToInt32(byteStreamSize, 0);
    byte[] messageOutput = new byte[streamSize];

    int offset = 0;
    while (offset < streamSize)
    {
        offset += stream.Read(messageOutput, offset, streamSize - offset);
    }

    string output = ASCIIEncoding.ASCII.GetString(messageOutput);

    return output;
}

Closing thoughts

SSL adds an extra layer of security to your communications, but it requires careful management of the certificate files. With this added layer comes added complexity. Fortunately, .net abstracts much of this work into an object that, with a little preparation, you can treat as any other Stream object.

Now you can focus on what your application is supposed to be doing!

Technologies Generation Y Will Replace

Posted in Personal on March 27th, 2009 by djurek – Be the first to comment

Nick Health has written a blog post on ZDNet about technologies that Generation Y will replace. I agree with many of his points. I disagree with some. The article is a great framework for briefly discussing the future.

Replaced technologies

Email

Nick asserts that the youths of today use email to communicate to the folks of older generations and little else. Having recently graduated college, I see where he’s coming from; I used email as little as possible. In college, Facebook, IM’s and text messages facilitated the majority of my interpersonal communication.

Now I work for my money. I assume much of Generation Y will too. Business requires a more robust and free-form environment for the communication of ideas. I can’t illustrate rich ideas in Facebook messages nor can I easily arrange meetings and reserve spaces using 160 character SMS messages. These tasks require a more versatile technology called e-mail.

If Nick is referring to the age-old model of POP/SMTP and text-only email, then I see where he’s coming from. Nick, we’ve already replaced these technologies. It’s entirely likely that we have a semantic disconnect here (see also: any two peoples’ definition of the cloud).

Websites

Right on! Most folks can’t author a web page, nor should they. Down with Geocities!

Datacenters

Based on the quote, Nick seems to think that all computing will become a utility (like electricity and water).

This is doubtful when considering that many government and private institutions will not tolerate the risk of downtime and disclosure. Especially disclosure.

I’m not averse to the idea of cloud computingsimply because the defnition is so nebulous. I do not believe that all private user and business data belongs in someone else’s datacenter. Though I do believe those people and institutions should be able to access their data anywhere.

Fixed line phones

Yes! Yes! You can see it happening right now. I only have a cellphone.

The personal computer

Ambiguity abounds. Nick seems to assert that personal computing sessions will live in the cloud, connecting through thin clients.

Most consumer PC needs could go to the cloud. OnLive, netbooks, and other technologies are questioning the necessity of computing power for consumer purposes. But the cloud will have to to deliver a lightning storm of rich user experience before users stop expanding their hardware.

I’d rather be writing this blog post from a netbook.

Traditional data processing

Nick promises that data will all be tagged and machine parsable. He points to XBRL as a solution. This reminds me of Tim Benders-Lee’s The Semantic Web, published back in 2001.

XBRL suffers from a heavy case of multi-institution collaborative scope creep. Human nature will sabotage these efforts as long as human nature persists.

Closing thoughts

I agree with Nick on many points, but I believe we should consider the practical implications of his many visionary points. Future technologies should:

  • Preserve privacy
  • Allow anonymity
  • Provide flexibility in input and representation
  • Be cheap and reliable

I’ll blog on these points and the cloud at a later date.

Speaking of the future, check out this cool video Microsoft published highlighting its vision. Who wants to take bets on whether 2019 will be this green and satisfying?

A Complaint Free Free World

Posted in Personal on March 11th, 2009 by djurek – Be the first to comment

I have ceased my complaint free world bracelet activity. Going in the metrics for success was a complaint free month. This was a very tough challenge and I learned many things along the way.

I did not reach my intended goal of 30 days complaint free. My longest streak was a short five days. But like so many other projects, I discovered that the “complaint free” aspect of my complaint free world attempt was hindering my ability to be effective in more important areas of my life. I did, however, learn several important lessons.

Think twice before letting something negative out

All too often I find myself focusing on the negative aspects of my world. This is especially challenging because sarcasm plays a large role in my ability to formulate humor.

If you don’t have something nice to say, reword it until it sounds nice.

It’s obvious

Most folks can find the things that displease them in this world on their own. Stating the obvious is an overrated skill. It’s much more interesting to state that which is not obvious.

Everyone can see that it’s cold and rainy outside.

I don’t care if you’re hungry

And you shouldn’t care if I am. Finding a solution to the problem is more important.

Give me the patience

Some things you can’t change. Most of the time the same problem is obvious to everyone else.

The economy is totally ready for some improvement.

Ah well.

Having said all of that, I can’t stand the way people in Seattle drive (I am also not alone in this opinion). The only way to fix the problem involves copious amounts of horn, fist shaking, and screaming with the window rolled down. I can’t take the time to teach you how to drive, but if I can scare you out of my way, I have saved us both the energy. And please, turn on your lights when you drive at night.

Not complaining was an interesting challenge and I think I have modified some of my behaviors for the better. Either way, I have helped myself to a little self help.