Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Websocket handshake Sec-WebSocket-Accept header value is incorrect

I'm writing a c++ websocket server, dev tools on chrome says sec-websocket-accept header value is incorrect. I've tested for days and it all seems fine. The client closes with readystate 3 without the websocket onopen being called although it shows as 101 in chrome dev tools.

This is my code for calculating the keys

string magickey = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
string key = msgkey.append(magickey);

unsigned char* sha_str = SHA1(reinterpret_cast<const unsigned char*>(key.c_str()), key.length(), nullptr);
string acceptkey = base64_encode(reinterpret_cast<const unsigned char*>(sha_str), strlen((char*)sha_str));

string handshake_response = "HTTP/1.1 101 Switching Protocols\r\n";
handshake_response.append("Upgrade: websocket\r\n");
handshake_response.append("Connection: Upgrade\r\n");
handshake_response.append("Sec-WebSocket-Accept: "+acceptkey+"\r\n");
handshake_response.append("\r\n");  

Chrome Response

HTTP/1.1 101 Switching Protocols  
Upgrade: websocket  
Connection: Upgrade  
Sec-WebSocket-Accept: 5T5MvxP1iz40vLpi3kQs/ifDaCo=  

Chrome Request

GET ws://localhost:4897/echo HTTP/1.1  
Host: localhost:4897  
Connection: Upgrade  
Pragma: no-cache  
Cache-Control: no-cache  
Upgrade: websocket  
Origin: http://localhost  
Sec-WebSocket-Version: 13  
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36  
Accept-Encoding: gzip, deflate, sdch  
Accept-Language: en-US,en;q=0.8  
Sec-WebSocket-Key: LKF8lHGznbKGIgO1UzAOhg==  
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits  

It says "Error during WebSocket handshake: Incorrect 'Sec-WebSocket-Accept' header value".

Chrome also shows one additional frame received size 79 bytes opcode -1.

Thanks Heaps!

like image 722
xmxmxmx Avatar asked Mar 14 '23 14:03

xmxmxmx


1 Answers

Chrome says that 'Sec-WebSocket-Accept' is incorrect. Trying to compute it manually, I have to agree with Chrome.

My test:

  1. concat "LKF8lHGznbKGIgO1UzAOhg==" and "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" => "LKF8lHGznbKGIgO1UzAOhg==258EAFA5-E914-47DA-95CA-C5AB0DC85B11", that's key.
  2. compute SHA1 160 bits hex: bf15 14e3 7108 0ee4 7782 c709 a767 cc72 423d e5c4
  3. From your log, your encoding to base64 is: 5T5MvxP1iz40vLpi3kQs/ifDaCo=
  4. Decoding it to hex: e53e 4cbf 13f5 8b3e 34bc ba62 de44 2cfe 27c3 682a

The bold values should be equal. Feel free to correct me if I'm wrong somewhere.

Possible problems:

  • Is sha_str null-terminated ? i.e. strlen((char*)sha_str) == 20 ?

  • signed/unsigned char mixup ?

like image 94
Ilya Avatar answered Apr 26 '23 00:04

Ilya