WebSockets握手从服务器端回复,草稿00

时间:2012-02-22 18:02:23

标签: c++ qt websocket md5

我正在编写一个小型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

通过连接数字并除以空格数计算密钥时,我得到以下两个整数: 155712099 173347027 (该文档也有这两个数字) )。

接下来,它说:

  1. 将它们分别转换为Big Endian
  2. 将结果连接成字符串并追加最后8位(Tm[K T2u)。
  3. 从步骤1和2中生成的字符串创建128位MD5总和。
  4. 有了这些知识,我就制作了以下代码:

    #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没有提及有关Endian转换的任何内容。我尝试了上面的代码而没有转换(维基百科示例和草案中的示例)仍然无法重现预期的结果。

    任何人都可以指出这里的问题是什么?


    编辑:

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

2 个答案:

答案 0 :(得分:2)

Herewebsockify的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会创建一个稍微大一些填充垃圾的数组。至少那是我的情况。