Search This Blog

Sunday, October 3, 2010

SSL Communication Between Applications

Summary:
The article shows the step by step procedure how to create the self signed certificate and how to configure the SSL connection. The example then implements the Https client server communication with using Eneter.Messaging.Framework.




Introduction
SSL (Secure Socket Layer) is a standard security protocol to verify the identity of communicating parts and establish the encrypted communication.

Here is how the communication works (if only the server is certified):
  1. The client connects the server and asks for the digital certificate.
  2. The client verifies the received certificate (i.e. if the certificate is issued by a trusted authority, if the domain from the certificate matches with the domain sending the certificate, ...)
  3. The client creates a session key, encrypts it with the public key from the received certificate and sends it to the server.
  4. The server decrypts the session key from the client and uses it to encrypt the content for the client.
  5. The client uses the session key to decrypt the content from the server.
Digital Certificate
The digital certificate is like an Id card. It identifies its owner. And same as in the real world, where ID cards are accepted only if they are issued by trusted authorities (If I create my own driver license, it would not be probably accepted by a policeman.), also digital certificates are accepted if they are issued by trusted authorities.
Therefore, it is important to check if the "Id card" can be accepted - i.e. if the digital certificate was issued (digital signed) by a trusted authority. Typically, for the world wide communication the certificate is issued by a third party mutually trusted authority (e.g. Verisign).


Self Signed Certificate
In case, the certificate does not have to be issued (digitally signed) by a trusted third party authority, we can generate our own self signed certificate (e.g. for testing purposes or internal intranet usage, ...).

1. Create Certificate:
  1. Execute Visual Studio command prompt with Administrator privileges.
  2. makecert -r -n CN="127.0.0.1" -eku 1.3.6.1.5.5.7.3.1 -ss my -sr localmachine -sky exchange 
    (Instead of 127.0.0.1 you can use your ip address or the domain name.
    Help for 'makecert' can be found here.)
2. Configure the certificate to be trusted:
  1. Execute from the command prompt:  mmc 
  2. Choose 'Add/Remove Snap-in...'



  3. Doubleclick 'Certificates'



  4. Choose 'Computer account'


  5. The new certificate should be found under 'Personal Certificates'.



  6. The new certificate is among personal certificates, but it is not trusted. When we double-click the certificate,  the following message will be there:  "This CA Root certificate is not trusted. To enable trust, install this certificate in the Trusted Root Certification Authorities store."



  7. To resolve this issue, copy and paste the new certificate into 'Trusted Root Certification Authorities'.



  8. The certificate is trusted now.



4. Configure the certificate for a desired ip address and port:
In our case, we configure the certificate for all ip addresses and the port 7788.
  1. Copy the 'Thumbprint' from the certificate, paste it to the notepad and remove spaces between numbers - this thumbprint data will be used in the next step.



  2. Configure the ip address and the port for the certificate. Use your own thumbprint data in the command.

    The command for Windows Vista:
    netsh http add sslcert ipport=0.0.0.0:7788 certhash=a357e3f991763516a4119153e137df24f88f18ac appid={00000000-0000-0000-0000-000000000000}

    The command for Windows XP:
    httpcfg set ssl /i 0.0.0.0:7788 /h a357e3f991763516a4119153e137df24f88f18ac
    (Note: You need to download HttpCfg.exe from Microsoft)

Https Client Server Communication
The self signed certificate is now ready, and we can use it for the client server communication.
The following example implements the simple client-server with using Eneter.Messaging.Framework.
(Full, not limited and for non-commercial usage free version of the framework can be downloaded from http://www.eneter.net/. The online help for developers can be found on http://www.eneter.net/OnlineHelp/EneterMessagingFramework/Index.html)



Sever application
The server is a simple application listening to request to count two numbers.

Important:
  • The server domain must be same as the certificate name. It is 127.0.0.1 in our case. Otherwise the certificate check will fail on the client side and the connection will not be established.
  • The server must be executes with sufficient user rights. Execute it as Administrator for debugging purposes. Otherwise the server will fail to start.
using System;
using Eneter.Messaging.DataProcessing.Serializing;
using Eneter.Messaging.EndPoints.TypedMessages;
using Eneter.Messaging.MessagingSystems.HttpMessagingSystem;
using Eneter.Messaging.MessagingSystems.MessagingSystemBase;


namespace HttpService
{
    // Message requesting counting of two numbers.
    public class MyRequestMessage
    {
        public int Number1 { get; set; }
        public int Number2 { get; set; }
    };

    // Message returning the counting result.
    public class MyResponseMessage
    {
        public int Result { get; set; }
    };

    class Program
    {
        static void Main(string[] args)
        {
            // Create messaging using Https.
            IMessagingSystemFactory aMessagingFactory = new HttpMessagingSystemFactory();
            IDuplexInputChannel anInputChannel = aMessagingFactory.CreateDuplexInputChannel("https://127.0.0.1:7788");

            // Create the message receiver that receives MyRequestMessage and resonses MyResponseMessage.
            IDuplexTypedMessagesFactory aTypedMessages = new DuplexTypedMessagesFactory(new XmlStringSerializer());
            IDuplexTypedMessageReceiver<MyResponseMessage, MyRequestMessage> aMessageReceiver = aTypedMessages.CreateDuplexTypedMessageReceiver<MyResponseMessage, MyRequestMessage>();
            
            // Subscribe to process incoming messages.
            aMessageReceiver.MessageReceived += MessageReceived;

            // Start listening for messages.
            Console.WriteLine("The server is listening.");
            aMessageReceiver.AttachDuplexInputChannel(anInputChannel);
        }

        // Processes incoming messages.
        static void MessageReceived(object sender, TypedRequestReceivedEventArgs<MyRequestMessage> e)
        {
            if (e.ReceivingError == null)
            {
                // Count incoming numbers.
                MyResponseMessage aResponse = new MyResponseMessage();
                aResponse.Result = e.RequestMessage.Number1 + e.RequestMessage.Number2;

                Console.WriteLine("Result = " + aResponse.Result.ToString());

                // Resonse the result back to the sender.
                IDuplexTypedMessageReceiver<MyResponseMessage, MyRequestMessage> aReceiver = (IDuplexTypedMessageReceiver<MyResponseMessage, MyRequestMessage>)sender;
                aReceiver.SendResponseMessage(e.ResponseReceiverId, aResponse);
            }
        }
    }
}

Client application
The client is a simple application sending the request to the server to count two numbers.
The whole implementation is here:

using System;
using Eneter.Messaging.DataProcessing.Serializing;
using Eneter.Messaging.EndPoints.TypedMessages;
using Eneter.Messaging.MessagingSystems.HttpMessagingSystem;
using Eneter.Messaging.MessagingSystems.MessagingSystemBase;

namespace HttpClient
{
    // Message requesting counting of two numbers.
    public class MyRequestMessage
    {
        public int Number1 { get; set; }
        public int Number2 { get; set; }
    };

    // Message returning the counting result.
    public class MyResponseMessage
    {
        public int Result { get; set; }
    };

    class Program
    {
        static void Main(string[] args)
        {
            // Create messaging using Https.
            IMessagingSystemFactory aMessagingFactory = new HttpMessagingSystemFactory();
            IDuplexOutputChannel anOutputChannel = aMessagingFactory.CreateDuplexOutputChannel("https://127.0.0.1:7788");

            // Create the message sender that sends MyRequestMessage and receive resonses MyResponseMessage.
            IDuplexTypedMessagesFactory aTypedMessages = new DuplexTypedMessagesFactory(new XmlStringSerializer());
            IDuplexTypedMessageSender<MyResponseMessage, MyRequestMessage> aMessageSender = aTypedMessages.CreateDuplexTypedMessageSender<MyResponseMessage, MyRequestMessage>();
            
            // Subscribe to handle responses.
            aMessageSender.ResponseReceived += ResponseReceived;
            
            // Attach the the Https channel to send request messages and receive response messages.
            aMessageSender.AttachDuplexOutputChannel(anOutputChannel);

            // Very simple loop getting numbers from the user and sending requests to the server.
            while (true)
            {
                MyRequestMessage aRequest = new MyRequestMessage();

                Console.Write("Number 1: ");
                aRequest.Number1 = int.Parse(Console.ReadLine());

                Console.Write("Number 2: ");
                aRequest.Number2 = int.Parse(Console.ReadLine());

                // Send the request to count inserted numbers.
                aMessageSender.SendRequestMessage(aRequest);
            }
        }

        // Handles received response messages.
        static void ResponseReceived(object sender, TypedResponseReceivedEventArgs<MyResponseMessage> e)
        {
            if (e.ReceivingError == null)
            {
                Console.WriteLine("Result: " + e.ResponseMessage.Result.ToString());
            }
        }
    }
}

I hope you found the article useful. If you would like to have more information about Eneter.Messaging.Framework, you can find it on www.eneter.net.

2 comments:

  1. Its a very well explained post. You have mentioned how to create self signed certificate and how to configure the SSL connection using a very interesting example. Thanks for summing all the things in such a simple way.
    electronic signature Microsoft

    ReplyDelete