WebSocket Protocol – Exact Definition of Sec-WebSocket-Key

protocolwebsockets

I'm wondering what the exact definition of the header-field Sec-Websocket-Key is.

The field is used for Websocket connections. The client asks the server to upgrade from HTML to Websocket. The request can look like this:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

The Sec-WebSocket-Key field is defined as follows [RFC6455]:

The |Sec-WebSocket-Key| header field is used in the WebSocket opening
handshake. It is sent from the client to the server to provide part
of the information used by the server to prove that it received a
valid WebSocket opening handshake. This helps ensure that the server
does not accept connections from non-WebSocket clients (e.g., HTTP
clients) that are being abused to send data to unsuspecting WebSocket
servers.

The |Sec-WebSocket-Key| header field MUST NOT appear more than once
in an HTTP request.

And also in [RFC6455]:

For this header field, the server has to take the value (as present
in the header field, e.g., the base64-encoded [RFC4648] version minus
any leading and trailing whitespace) and concatenate this with the
Globally Unique Identifier (GUID, [RFC4122]) "258EAFA5-E914-47DA-
95CA-C5AB0DC85B11" in string form, which is unlikely to be used by
network endpoints that do not understand the WebSocket Protocol. A
SHA-1 hash (160 bits) [FIPS.180-3], base64-encoded (see Section 4 of
[RFC4648]), of this concatenation is then returned in the server's
handshake. Concretely, if as in the example above, the
|Sec-WebSocket-Key| header field had the value
"dGhlIHNhbXBsZSBub25jZQ==", the server would concatenate the string
"258EAFA5-E914-47DA-95CA-C5AB0DC85B11" to form the string
"dGhlIHNhbXBsZSBub25jZQ==258EAFA5-E914-47DA-95CA- C5AB0DC85B11".
The server would then take the SHA-1 hash of this, giving the value
0xb3 0x7a 0x4f 0x2c 0xc0 0x62 0x4f 0x16 0x90 0xf6 0x46 0x06 0xcf
0x38 0x59 0x45 0xb2 0xbe 0xc4 0xea. This value is then
base64-encoded (see Section 4 of [RFC4648]), to give the value
"s3pPLMBiTxaQ9kYGzzhZRbK+xOo=". This value would then be echoed in
the |Sec-WebSocket-Accept| header field.

I've completly understood the purpose of this field. However, I can not find any information on how exactly it is generated.

Probably it is not just a random string with random length and a random charset.

Best Answer

The Sec-WebSocket-Key is a completely random string with a length of 16 bytes, and has an allowable range of ASCII value 32 to 127.

You start with an empty string. Then as long as you generate a character that is within the ASCII range 32 to 127, you add to this string.

Once you reached 16 ASCII characters, stop, and base64 encode the resultant string.

Related Topic