当前位置: 首页 > 知识库问答 >
问题:

WebSocket握手:不正确的Sec-WebSocket-Access标头值

王宜
2023-03-14

我正在用C编写一个websocket服务器,无法让握手正常工作。Chrome报告错误是由于错误的accept头,但我相信该值是正确的。

作为exchange的一个示例,客户端发送以下密钥:

Sec-WebSocket-Key: ypX0m2zum/pt80mxlVo8PA==

我的服务器会发回:

Sec-WebSocket-Accept: Kl4mnqm5QA6bBmGf3EAN0nyGXws=

我已经根据RFC中的示例测试了我的服务器,并进行了验证。我不知道为什么不被接受。我的理论是,我必须做一些其他事情,产生与坏接受值相同的错误。

以下是不同于wireshark捕获的请求:

Hypertext Transfer Protocol
    GET /websocket HTTP/1.1\r\n
    Host: 127.0.0.1:8443\r\n
    Connection: Upgrade\r\n
    Pragma: no-cache\r\n
    Cache-Control: no-cache\r\n
    User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36\r\n
    Upgrade: websocket\r\n
    Origin: chrome-extension://eajaahbjpnhghjcdaclbkeamlkepinbl\r\n
    Sec-WebSocket-Version: 13\r\n
    Accept-Encoding: gzip, deflate, br\r\n
    Accept-Language: en-US,en;q=0.9\r\n
    Sec-WebSocket-Key: +zJ3/KI/Zrumgh+AjxopRQ==\r\n
    Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n
    \r\n
    [Full request URI: http://127.0.0.1:8443/websocket]
    [HTTP request 1/1]
    [Response in frame: 6]

以下是回应:

Hypertext Transfer Protocol
    HTTP/1.1 101 Switching Protocols\r\n
    Upgrade: websocket\r\n
    Connection: Upgrade\r\n
    Sec-WebSocket-Accept: anTEIFyI/gTepr8Q3okBj81M2/4=\r\n
    \r\n
    [HTTP response 1/1]
    [Time since request: 0.000245010 seconds]
    [Request in frame: 4]

有人能告诉我这个回答有什么问题吗?我的接受值是否不正确?

编辑1:

我用来创建响应值的代码。在此之前,会从请求中获取websocket_密钥。

    const char *magic_string = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

    int pre_hash_size = 36 + websocket_key.size();
    char pre_hash[pre_hash_size];

    memcpy(pre_hash, websocket_key.c_str(), websocket_key.size());
    memcpy(pre_hash + websocket_key.size(), magic_string, 36);

    unique_ptr<Botan::HashFunction> hash1(Botan::HashFunction::create("SHA-1"));
    Botan::secure_vector<uint8_t> post_hash = hash1->process(reinterpret_cast<const uint8_t *>(pre_hash), pre_hash_size);

    string accept_response = base64_encode(post_hash.data(), post_hash.size());

下面是base 64函数:

/* 
   base64.cpp and base64.h
   base64 encoding and decoding with C++.
   Version: 1.01.00
   Copyright (C) 2004-2017 René Nyffenegger
   This source code is provided 'as-is', without any express or implied
   warranty. In no event will the author be held liable for any damages
   arising from the use of this software.
   Permission is granted to anyone to use this software for any purpose,
   including commercial applications, and to alter it and redistribute it
   freely, subject to the following restrictions:
   1. The origin of this source code must not be misrepresented; you must not
      claim that you wrote the original source code. If you use this source code
      in a product, an acknowledgment in the product documentation would be
      appreciated but is not required.
   2. Altered source versions must be plainly marked as such, and must not be
      misrepresented as being the original source code.
   3. This notice may not be removed or altered from any source distribution.
   René Nyffenegger rene.nyffenegger@adp-gmbh.ch
*/

static const std::string base64_chars =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "abcdefghijklmnopqrstuvwxyz"
    "0123456789+/";

std::string base64_encode(unsigned char const *bytes_to_encode, unsigned int in_len)
{
  std::string ret;
  int i = 0;
  int j = 0;
  unsigned char char_array_3[3];
  unsigned char char_array_4[4];

  while (in_len--)
  {
    char_array_3[i++] = *(bytes_to_encode++);
    if (i == 3)
    {
      char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
      char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
      char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
      char_array_4[3] = char_array_3[2] & 0x3f;

      for (i = 0; (i < 4); i++)
        ret += base64_chars[char_array_4[i]];
      i = 0;
    }
  }

  if (i)
  {
    for (j = i; j < 3; j++)
      char_array_3[j] = '\0';

    char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
    char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
    char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);

    for (j = 0; (j < i + 1); j++)
      ret += base64_chars[char_array_4[j]];

    while ((i++ < 3))
      ret += '=';
  }

  return ret;
}

共有1个答案

堵龙野
2023-03-14

问题是,当我连接来自websocket键(由客户端发送)的pre_散列字符串和神奇字符串(常量)时,我没有考虑 size()函数在其计数中包含的空终止符。 我在解析请求头时无意中添加了额外的空间。

 类似资料:
  • 我正在使用Python的套接字来响应Websocket请求,并且我面临着头的问题。以前可能有过类似的问题,但没有人为我工作 文档位于https://developer.mozilla.org声明对于要建立的连接: 服务器获取握手请求中发送的Sec-WebSocket-Key的值,追加258EAFA5-E914-47DA-95CA-C5AB0DC85B11,获取新值的SHA-1,然后对其进行Bas6

  • 我正在使用Windows server 2019,反向代理配置为ARR 3,并使用节点托管我的项目。js和socket。io,我正在重定向网站至内部地址。 当我尝试访问网站时在服务器套接字内。io正在工作,但当我尝试使用外部地址访问网络外部的网站时,我收到了错误消息 Web套接字握手期间出错:“Sec WebSocket Accept”标头值不正确

  • 我正在写一个c websocket服务器,chrome上的开发工具说SecWebSocket接受头值不正确。我已经测试了好几天了,一切似乎都很好。客户端使用readystate 3关闭,而不调用websocket onopen,尽管它在chrome开发工具中显示为101。 这是我计算钥匙的代码 铬反应 Chrome请求 它表示"WebSocket握手过程中出错:不正确的'Sec-WebSocket

  • ASP.NET 5 RC1上的信号器3-RC1用户 尝试运行websocket时出现以下错误。 使用Chrome50.0.2661.87 标题如下: 请求标题: 日期:2016年4月29日星期五13:51:54 GMT 服务器:Kestrel 传输编码:分块 升级:websocket X-Content-Type-Options:nosniff X-Powered-By:ASP.NET 响应头:

  • 我正在做我的第一个测试,尝试使用phpwebsocket。 我将其握手标题值设置为以下值: 所以我运行web套接字PHP文件(创建连接),一切正常。 因此,我运行测试html,其中包含一个脚本,该脚本试图连接到我正在使用的phpwebsocket,在浏览器控制台中,我收到以下错误: 但是我发现这个错误在WebSocket握手:不正确的'Sec-WebSocket接受'头值与PHP,这是通过定义缓冲

  • 我似乎得到了错误的哈希值通过我的webSocket键。据我所知,套接字的客户端工作,因为当我让它连接到其他服务器时,它是成功的。 指数js 指数html 运行时密钥和哈希对的示例如下: PxsrStN1CGLK/JBYydUFjg== QAK TE6u sV705GI LpP4yKM04Y= 顶部是浏览器给出的键,底部是getAVal函数返回的值,它是不正确的,导致此消息。 WebSocket握手