Хэш рукопожатия WebSocket неверен после кодирования - PullRequest
0 голосов
/ 09 мая 2019

Я пишу приложение сервера сокетов TCP для приема данных из приложения Angular.В серверном приложении я хочу вернуть заголовок ответа на запрос веб-сокета, однако при генерации base64 хеша я получаю значение, которое является длинным (и неправильным), и поэтому квитирование не выполняется.

Я использую класс TNetCoding в блоке System.NetEncoding для кодирования.Пример можно найти по адресу https://flixengineering.com/archives/270.

Я получаю что-то вроде:

YWRiYzRlYmJiMDkyZmM2MzNjMGJjMGZjNGY0YjQwOTllZjVhNWMxMw = *

1011 * *1012* 1011 * *1012* 1011 * *1012* 1011 * *1012* 1011 * *1012* 1011 * *1012* 1011 * *1012* 1011 * *1012* 1011 * *1012* 1011 * *1012* 1011 * *1012* 1011 * *1012* 1011 * *1012* 1011 * *1012* 1011 * *1012* 1011 * *1012* 1011 * *1012* 1011 * *1012* 1011 * *1012* 1011 * *1012* 1011 * *1012* 1013 *1012* 1013*

Входящий запрос:

GET / HTTP/1.1
Host: localhost:12345
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: http://localhost:4200
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Sec-WebSocket-Key: ky8at6EtBZLocDhJU7hMnw==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

Сгенерировано хэша:

c289980eb715b3e19107152dc21f075c9f7bf539

Сгенерирована строка Base64:

YzI4OTk4MGViNzE1YjNlMTkxMDcxNTJkYzIxZjA3NWM5ZjdiZjUzOQ ==

Обновление: Вот еще один пример:

1035 * 10 * 2G2O3SoD3362S3D3S3D3S3D3323S3D3323S3323*

Десятичное значение, отображаемое при отладке:

image

Сгенерированная строка:

F68FCEE74F044B57E9047395B975A31A6ABEBDD2

1 Ответ

0 голосов
/ 10 мая 2019

Правильный хэш SHA1 для объединенной строки

ky8at6EtBZLocDhJU7hMnw == 258EAFA5-E914-47DA-95CA-C5AB0DC85B11

это (проверено несколькими хэш-сайтами SHA1 онлайн):

51D265858FE3CF00E77A63FBC2C2327D89579B07

Не так, как вы показали:

c289980eb715b3e19107152dc21f075c9f7bf539

Итак, ваше рукопожатие WebSocket не удается из-за неправильного хеширования.

Кроме того, поскольку THashSHA1.GetHashString() возвращает шестнадцатеричную строку , которая является кодировкой base64, но вам нужно base64 кодировать необработанных хеш-байтов , а не шестнадцатеричную строку представление этих байтов.

Попробуйте это:

procedure TServerForm.SendHeader(key: string);
var
  encod, ret: TBytes;
const
  magic = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
begin
  ret := THashSHA1.GetHashBytes(key + magic);
  encod := TNetEncoding.Base64.Encode(ret);
  CliSocket.SendStr('HTTP/1.1 101 Switching Protocols' + #13#10 +
                    'Upgrade: websocket' + #13#10 +
                    'Connection: Upgrade' + #13#10 +
                    'Sec-WebSocket-Accept: ' + TEncoding.ASCII.GetString(encod) + #13#10 +
                    #13#10);
  Memo2.Lines.Add('Header was sent');
end;

Сгенерированный base64 должен быть:

UdJlhY / jzwDnemP7wsIyfYlXmwc =

...