KappS
KappS

Reputation: 41

C# - Implement Secure Web Socket

I would like to ask if you know how to implement Secure Web Socket with .Net. I've implemented ws:// and everything ok but I've no idea how to switch to wss://. Thanks in advance.

Upvotes: 0

Views: 10369

Answers (3)

Tharindu Nilakshana
Tharindu Nilakshana

Reputation: 61

If you use WebSocketSharp-NonPreRelease Package to develop the websocket you can simply add your certificate using below code

var wssv = new WebSocketServer (5963, true);
wssv.SslConfiguration.ServerCertificate =
  new X509Certificate2 ("/path/to/cert.pfx", "password for cert.pfx");

Upvotes: 0

Davide C
Davide C

Reputation: 116

This question is very old but here's how i got my C# server accept an SSL connection from the client (js code running on Chrome / Firefox).

Assuming you already have a working and valid certificate (in my case the same certificate working to serve SSL on my Apache webserver), signed by a trusted CA (in my case, letsencrypt.org, which let you request a certificate for free), this is an excerpt from working code:

public static X509Certificate2 serverCertificate = null;

public Server(string ip_addr, int port)
{
        serverCertificate = GetCertificateFromStore("CN=mydomain.com");

        string resultsTrue = serverCertificate.ToString(true); // Debugging purposes
        bool hasPrivateKey = serverCertificate.HasPrivateKey; // Debugging purposes (MUST return true)
        Console.WriteLine("Certificate validation results: " + resultsTrue);
        Console.WriteLine("Has private key? " + hasPrivateKey);
        server = new TcpListener(IPAddress.Parse(ip_addr), port);

        server.Start();

        Console.WriteLine("Server has started on ip: " + ip_addr + ":"+port + " - Waiting for a connection...", Environment.NewLine);
 }

 public class ClientHandler
 {
    TcpClient client { get; set; }
    //NetworkStream stream { get; set; } // Old plain non-secure tcp stream
    SslStream stream { get; set; } // New secure tcp stream

    ....

    public ClientHandler(TcpClient client, string room_id)
    {
        ....
        stream = new SslStream(client.GetStream(), false);
        try
        {
            stream.AuthenticateAsServer(Server.serverCertificate, clientCertificateRequired: false, checkCertificateRevocation: false);

            // Set timeouts for the read and write to 5 seconds.
            stream.ReadTimeout = 5000;
            stream.WriteTimeout = 5000;
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error during SSL authentication with the client:" + ex);
            return;
        }
    }
}

The tricky part is that class X509Certificate2 needs to retrieve the certificate not from file but from your local keystore. Also you need both the certificate file AND your private key for SSL to work.

I'm developing on Linux and Mono.Net but it should not change much on other platforms. The tools i needed were: openssl and certmgr (mono certificate manager).

To create the .pfx file containing the cert & the private key:

openssl pkcs12 -export -in yourcertfile.cer -inkey yourprivatekeyfile.pem -out finalfile.pfx

To add the file obtained to my local store:

certmgr -add -c -m Trust finalfile.pfx 

Finally, you can edit your client side connection code to point to the same domain you're hosting your server (which should be the same domain reported in your certificate).

This:

var mySocket = new WebSocket("ws://127.0.0.1:5050");

Becomes:

var mySocket = new WebSocket("wss://yourdomain.com:5050");

Keep in mind that, once you've implemented SSL, you'll have to revise the whole networking code, since you're adding overhead to your TCP stream and you must take it into account when parsing the bytes and the bits to find and decode the headers. This is where i'm stuck myself but beside that, SSL connection works great :)

Upvotes: 0

Mel Gerats
Mel Gerats

Reputation: 2252

You could try Fleck

Fleck is a WebSocket server implementation in C#

From their examples:

var server = new WebSocketServer("wss://0.0.0.0:8431");
server.Certificate = new X509Certificate2("MyCert.pfx");
server.Start(socket =>
{
  //...use as normal
});

Upvotes: 2

Related Questions