Websocket Handshake
in Articles,
by Marnix
last published on 26 September 2021
Recently, I have been tinkering with new technologies the latest browsers have started to integrate, in particular WebSockets. One of the things I have been trying to do, is setup a WebSockets server in C++ on Windows. After reading a number of articles on the new socket protocol I thought I had it all figured out.
Unfortunately, after implementing a simple multi-threaded socket server, and overlaying the WebSocket protocol over the Chrome browser refused to connect to it.
After some additional research I figured out that, for security reasons, the latest draft of the WebSocket standard contains additional security measures. This article describes how one interprets this challenge so that your server can respond properly.
You can find the original draft document here: Websockets draft #76
Additional headers
There is some additional information that is sent from the client to the server, so the web browser knows that the server is not just any server. But:
- a proper websocket server;
- a server that knows about security measures in websockets protocol; and
- it prevents man-in-the-middle attacks.
When a websocket connection is first openend from the client to the server, it will send a number of headers to the server, not unlike the original HTTP protocol. Of most importance to us are the following headers:
- Sec-WebSockets-Key1;
- Sec-WebSockets-Key2; and
- the eight bytes that is a 64-bit value we will need later.
The keys contain all kinds of characters: letters, numbers and spaces. For each key, you need to count the number of spaces and take the digits and put them in a row, so for this key:
"1\} a`;l022aaf 51"
The results would be: 102251 and 4 spaces.
Once you get these numbers, divide the large number by the number of spaces. Do this for both keys.
Then, take the 64-bit number you retrieved last and make a 128-bit number, as follows:
128 64 32 0 |------------------|--------|--------| 128-bits 64-bit handshake key2 key1
Consequently, create an MD5 hash from this concatenated number, the 128-bit number that is the result of this is written in the response to the client.
And that's how you do a proper Websocket handshake! When the time is right I will release the C++/WebSockets code online so you can fiddle with it yourself.