来自服务器端的 WebSockets 握手回复,草稿 00

Posted

技术标签:

【中文标题】来自服务器端的 WebSockets 握手回复,草稿 00【英文标题】:WebSockets handshake reply from server side, draft 00 【发布时间】:2012-02-22 18:02:23 【问题描述】:

我正在编写一个小型 WebSocket 服务器应用程序,它应该同时支持 draft 17 和旧版本,例如 draft 00。我对最新的草稿没有任何问题,但我无法让草稿 00 客户满意。

出于测试目的,我使用了官方(旧)draft 00 docuemnt 第 7 页中提供的示例:

Sec-WebSocket-Key1: 18x 6]8vM;54 *(5:     U1]8  z [  8
Sec-WebSocket-Key2: 1_ tx7X d  <  nw  334J702) 7]o` 0

Tm[K T2u

当通过连接数字并除以空格计数来计算键时,我得到以下两个整数:155712099173347027(文档也有这两个数字)。

接下来,它说:

    将它们单独转换为 Big Endian 将结果连接成一个字符串并附加最后八位 (Tm[K T2u)。 从第 1 步和第 2 步中生成的字符串创建一个 128 位 MD5 和。

有了这些知识,我编写了以下代码:

#define BYTE    8
#define WORD    16

// Little Endian to Big Endian short
#define LE_TO_BE_SHORT(SHORT)\
    (((SHORT >> BYTE) & 0x00FF) | ((SHORT << BYTE) & 0xFF00))

// Little Endian to Big Endian long
#define LE_TO_BE_LONG(LONG)\
    (((LE_TO_BE_SHORT(LONG >> WORD)) | \
     ((LE_TO_BE_SHORT((LONG & 0xFFFF)) << WORD))))

uint num1 = LE_TO_BE_LONG(155712099);
uint num2 = LE_TO_BE_LONG(173347027);

QString cookie = QString::fromUtf8("Tm[K T2u");
QString c = QString::number(num1) + QString::number(num2) + cookie;

QByteArray data = c.toUtf8();
qDebug() << QCryptographicHash::hash(data, QCryptographicHash::Md5);

这是我得到的:

←→»α√r¼??┐☺║Pa♠µ

这是预期的(同样,基于草稿示例)

fQJ,fN/4F4!~K~MH

另一方面,我注意到wikipedia article 没有提到任何关于字节序转换的内容。我在没有转换的情况下尝试了上面的代码(***示例和草稿中的示例),但仍然无法重现预期结果。

谁能指出这里有什么问题?


编辑:

我发现this document 对协议有​​更好的解释。这是一个不同的草案(76),但在握手方面类似于 00。

【问题讨论】:

【参考方案1】:

Here是websockify的C实现中的计算。我知道这很有效,因此您可以将其用作参考。

【讨论】:

+1 谢谢,我也在添加我的解决方案,因为你正在回答:)【参考方案2】:

终于在同事们的新眼光的帮助下,我弄清楚了我做错了什么。基本上,我实际上是将两个整数连接成一个字符串。相反,我需要连接字节:

uint num1 = LE_TO_BE_LONG(155712099); // macros definition can
uint num2 = LE_TO_BE_LONG(173347027); // be found in the question
QString cookie = QString::fromUtf8("Tm[K T2u");

QByteArray array;

array =  QByteArray((const char*)&num1, sizeof(int));
array += QByteArray((const char*)&num2, sizeof(int));
array += QByteArray(cookie.toStdString().data(), cookie.length());

qDebug() << QCryptographicHash::hash(array, QCryptographicHash::Md5);

确保不要使用不占用大小的重载构造函数,因为 Qt 会创建一个稍大的数组,其中填充了垃圾。至少我的情况是这样。

【讨论】:

以上是关于来自服务器端的 WebSockets 握手回复,草稿 00的主要内容,如果未能解决你的问题,请参考以下文章

无法解码来自客户端的握手请求

Websockets:从NodeJS websocket服务器到带有WebSocketSharp的C#客户端的多个响应

SSL四次握手

websocket握手问题

QT - WebSockets

计算机网络HTTPS协议中SSL/TLS四次握手过程