C++ - WebSockets是否强制执行加密,如何获得"plaintext"?

C++ - Do WebSockets enforce encryption, how to get "plaintext"?

本文关键字:何获得 plaintext 加密 WebSockets 是否 强制执行 C++      更新时间:2023-10-16

我的朋友正在学习如何在他的web服务器上乱用WebSockets,所以我决定尝试学习如何升级我的HTTP/1.1连接到WebSockets,这已经成功地工作了!但我用新的websocket协议发送数据但我检索的信息是加密/压缩的

所以我的问题是

  1. 数据是否加密/压缩?
  2. 我如何能够检索明文?
  3. WebSockets像TCP连接吗?(我知道WebSockets是建立在HTTP上的,而HTTP是建立在TCP上的),但我知道它们支持双向流,所以我有点认为明文会被接收。

代码:(这根本没有调试,因为我只是快速地将其连接到WebSocket echo服务器,我发现它与Fiddler混淆)

    int main()
{
WSADATA WsaData = { 0 };
WSAStartup(MAKEWORD(2, 2), &WsaData);
addrinfo hints = { 0 }, *results = nullptr;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = AF_INET;
getaddrinfo("echo.websocket.org", "80", &hints, &results);
SOCKET hSocket = socket(results->ai_family, results->ai_socktype, results->ai_protocol);
connect(hSocket, results->ai_addr, static_cast<int>(results->ai_addrlen));
std::string SendBuffer;
SendBuffer = "GET http://echo.websocket.org HTTP/1.1rn";
SendBuffer += "Host: echo.websocket.orgrn";
SendBuffer += "Upgrade: websocketrn";
SendBuffer += "Connection: Upgradern";
SendBuffer += "Origin: http://www.websocket.orgrn";
SendBuffer += "Sec-WebSocket-Key: BBw/08+HrO3UfLPU/jeq1g==rn";
SendBuffer += "Sec-WebSocket-Version: 13rn";
SendBuffer += "Sec-WebSocket-Protocol: chatrnrn";

char RecvBuffer[1024], MessageBuffer[50];
int ReturnCode = 0;
ReturnCode = send(hSocket, SendBuffer.c_str(), SendBuffer.length(), 0);
ReturnCode = recv(hSocket, RecvBuffer, 5000, 0);
ReturnCode = send(hSocket, "Hello!", 7, 0);
ReturnCode = recv(hSocket, MessageBuffer, 50, 0);

    return 0;
}

WebSocket协议升级响应:

HTTP/1.1 101 Web Socket Protocol Handshake
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Headers: authorization
Access-Control-Allow-Headers: x-websocket-extensions
Access-Control-Allow-Headers: x-websocket-version
Access-Control-Allow-Headers: x-websocket-protocol
Access-Control-Allow-Origin: http://www.websocket.org
Connection: Upgrade
Date: Wed, 19 Oct 2016 23:54:17 GMT
Sec-WebSocket-Accept: 6+RXVMNG1sZqeIs/Y1tlISzHAFI=
Server: Kaazing Gateway
Upgrade: websocket

发送数据到WebSocket响应:

x2x3ê

请阅读RFC 6455,它定义了WebSocket协议。特别是第5节:数据框架和第6节:发送和接收数据。

WebSocket不是纯文本协议。它实际上是一个使用框架消息的二进制协议,其中可以包含文本数据:

成功握手后,客户端和服务器以本规范中称为"消息"的概念单位来回传输数据。在网络上,消息由一个或多个帧组成。WebSocket消息不一定对应于一个特定的网络层帧,因为一个碎片化的消息可能被一个中介合并或分割。

框架有一个关联的类型。属于同一消息的每个帧都包含相同类型的数据。从广义上讲,有文本数据(被解释为UTF-8 [RFC3629]文本)、二进制数据(其解释留给应用程序)和控制帧(不打算为应用程序携带数据,而是用于协议级信令,例如表示连接应该关闭)的类型。这个版本的协议定义了六种帧类型,并保留了十种以供将来使用。

你的代码根本没有考虑到这一点。就套接字代码而言,唯一的纯文本部分是初始的HTTP升级握手。握手完成后,您必须发送和接收带帧的二进制消息。不幸的是,帧过程有点复杂。

你最好的选择是根本不手动实现WebSocket,而是使用现有的WebSocket库,如libwebsockets, WebSocket++, easywsclient等。

在你的升级响应中,你明确地告诉服务器你允许压缩:

SendBuffer += "Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bitsrnrn";

如果不需要压缩,请删除permessage-deflate扩展名。

https://en.wikipedia.org/wiki/DEFLATE