C++;Sha1的Base64-WebSocket握手 我目前正在尝试运行一个可以与WebSoCub通信的C++服务器。握手包括两个步骤,最后一个步骤我没有成功

C++;Sha1的Base64-WebSocket握手 我目前正在尝试运行一个可以与WebSoCub通信的C++服务器。握手包括两个步骤,最后一个步骤我没有成功,c++,binary,hex,websocket,handshake,C++,Binary,Hex,Websocket,Handshake,第一步是生成一个SHA1编码的字符串,我成功地获得了正确的十六进制字符串。(例如&) 在这两种情况下,我的输出与文档中所述的相同: Wikipedia: 1d 29 ab 73 4b 0c 95 85 24 00 69 a6 e4 e3 e9 1b 61 da 19 69 My Server: 1d 29 ab 73 4b 0c 95 85 24 00 69 a6 e4 e3 e9 1b 61 da 19 69 IETF Docu: b3 7a 4f 2c c0 62 4f 16 90 f6

第一步是生成一个SHA1编码的字符串,我成功地获得了正确的十六进制字符串。(例如&)

在这两种情况下,我的输出与文档中所述的相同:

Wikipedia: 1d 29 ab 73 4b 0c 95 85 24 00 69 a6 e4 e3 e9 1b 61 da 19 69
My Server: 1d 29 ab 73 4b 0c 95 85 24 00 69 a6 e4 e3 e9 1b 61 da 19 69

IETF Docu: b3 7a 4f 2c c0 62 4f 16 90 f6 46 06 cf 38 59 45 b2 be c4 ea
My Server: b3 7a 4f 2c c0 62 4f 16 90 f6 46 06 cf 38 59 45 b2 be c4 ea
所以这是对的。当我现在进行Base64编码时,我得到以下结果:

Wikipedia: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
My Server: MWQyOWFiNzM0YjBjOTU4NTI0MDA2OWE2ZTRlM2U5MWI2MWRhMTk2OQ==

IETF Docu: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
My Server: YjM3YTRmMmNjMDYyNGYxNjkwZjY0NjA2Y2YzODU5NDViMmJlYzRlYQ==
这是完全不同的。我确认我的Base64算法在某些在线转换器上工作,它们都产生了我的服务器的输出。所以问题是输入格式。我在一个javascript论坛中发现了一个论坛条目,其中一个有相同的问题,答案是,我们应该传递20个字符的二进制表示,而不是传递40个字符的十六进制字符串

我知道openssl SHA1返回二进制表示,但由于某些原因,我无法使用该库。我使用的SHA1库将编码的输出放在int数组中。输出如下所示(IETF示例):

我将其转换为十六进制,如下所示:

std::ostringstream oss;
oss << std::setfill('0');
            for (int i = 0; i < 5; ++i) {
                    oss << std::setw(8) << std::hex << result[i];
            }
std::ostringstream oss;

oss大多数Baser64编码器需要一个字节数组/二进制数据流。您希望使用位掩码和逻辑移位将整数拆分为字节。在32位系统上,每个int包含4个字节,您可以按如下方式提取它们:

for(i = 0; i < 5; i++) {

    byteResult[(i * 4) + 0] = result[i] & 0x000000ff;
    byteResult[(i * 4) + 1] = (result[i] & 0x0000ff00) >> 8;
    byteResult[(i * 4) + 2] = (result[i] & 0x00ff0000) >> 16;
    byteResult[(i * 4) + 3] = (result[i] & 0xff000000) >> 24;
}
(i=0;i<5;i++)的
{
byteResult[(i*4)+0]=结果[i]&0x000000ff;
byteResult[(i*4)+1]=(结果[i]&0x0000ff00)>>8;
byteResult[(i*4)+2]=(结果[i]&0x00ff0000)>>16;
byteResult[(i*4)+3]=(结果[i]&0xff000000)>>24;
}
其中,
byteResult
是比结果数组大4倍的字节[]。我假设字节被打包到int中的顺序,可能是相反的


将此字节[]传递到Base64编码器

大多数Baser64编码器需要一个字节数组/二进制数据流。您希望使用位掩码和逻辑移位将整数拆分为字节。在32位系统上,每个int包含4个字节,您可以按如下方式提取它们:

for(i = 0; i < 5; i++) {

    byteResult[(i * 4) + 0] = result[i] & 0x000000ff;
    byteResult[(i * 4) + 1] = (result[i] & 0x0000ff00) >> 8;
    byteResult[(i * 4) + 2] = (result[i] & 0x00ff0000) >> 16;
    byteResult[(i * 4) + 3] = (result[i] & 0xff000000) >> 24;
}
(i=0;i<5;i++)的
{
byteResult[(i*4)+0]=结果[i]&0x000000ff;
byteResult[(i*4)+1]=(结果[i]&0x0000ff00)>>8;
byteResult[(i*4)+2]=(结果[i]&0x00ff0000)>>16;
byteResult[(i*4)+3]=(结果[i]&0xff000000)>>24;
}
其中,
byteResult
是比结果数组大4倍的字节[]。我假设字节被打包到int中的顺序,可能是相反的


将此字节[]传递到Base64编码器

我在用c测试websocket时发现字节顺序错误。调整顺序(相反)解决了我的base64编码问题,产生了正确的接受密钥字符串:

unsigned char byteResult [20];
    for(i = 0; i < 5; i++) {
        byteResult[(i * 4) + 3] = sha.result[i] & 0x000000ff;
        byteResult[(i * 4) + 2] = (sha.result[i] & 0x0000ff00) >> 8;
        byteResult[(i * 4) + 1] = (sha.result[i] & 0x00ff0000) >> 16;
        byteResult[(i * 4) + 0] = (sha.result[i] & 0xff000000) >> 24;
    }
unsigned char byteResult[20];
对于(i=0;i<5;i++){
byteResult[(i*4)+3]=sha.result[i]&0x000000ff;
byteResult[(i*4)+2]=(sha.result[i]&0x0000ff00)>>8;
byteResult[(i*4)+1]=(sha.result[i]&0x00ff0000)>>16;
byteResult[(i*4)+0]=(sha.result[i]&0xff000000)>>24;
}

我在用c测试websocket时发现字节顺序错误。调整顺序(相反)解决了我的base64编码问题,产生了正确的接受密钥字符串:

unsigned char byteResult [20];
    for(i = 0; i < 5; i++) {
        byteResult[(i * 4) + 3] = sha.result[i] & 0x000000ff;
        byteResult[(i * 4) + 2] = (sha.result[i] & 0x0000ff00) >> 8;
        byteResult[(i * 4) + 1] = (sha.result[i] & 0x00ff0000) >> 16;
        byteResult[(i * 4) + 0] = (sha.result[i] & 0xff000000) >> 24;
    }
unsigned char byteResult[20];
对于(i=0;i<5;i++){
byteResult[(i*4)+3]=sha.result[i]&0x000000ff;
byteResult[(i*4)+2]=(sha.result[i]&0x0000ff00)>>8;
byteResult[(i*4)+1]=(sha.result[i]&0x00ff0000)>>16;
byteResult[(i*4)+0]=(sha.result[i]&0xff000000)>>24;
}

在一个稍微相关的注释上(我看到您已经发现了…):

结果[0]=3011137324
...

oss在一个稍微相关的注释上(我看到您已经发现了…):

结果[0]=3011137324
...

oss真棒,我将尽快试用它,非常抱歉,但它不起作用:(结果是一个5的数组,所以我不需要枚举,直到我<5?它也会产生非常奇怪的输出。很抱歉,你说得很对,应该是5-答案更新。另请参阅我关于字节排序的说明。输出以什么方式奇怪?这是byteresult:,Oz�Ob�F��EY8��ľ�B37A4F2CC0624F1690F64606CF385945B2BEC4EA您的Base64编码器接受什么输入?您是否直接将字节[]传递给它?太棒了,我会尽快试用它。非常抱歉,它不起作用:(结果是一个5的数组,所以在i<5之前我不必枚举吗?它也会产生非常奇怪的输出。很抱歉,你说得很对,应该是5-答案更新。另请参阅我关于字节排序的说明。输出以什么方式奇怪?这是byteresult:,Oz。)�Ob�F��EY8��ľ�B37A4F2CC0624F1690F64606CF385945B2BEC4EA您的Base64编码器接受什么输入?您是否直接将字节[]传递给它?谢谢。在这里您可以看到我是如何修复它的(方法连接::身份验证()谢谢。在这里您可以看到我是如何修复它的(方法连接::身份验证()