Websocket 密钥散列
Posted
技术标签:
【中文标题】Websocket 密钥散列【英文标题】:Websocket key hashing 【发布时间】:2016-04-04 18:30:38 【问题描述】:我有一个简单的函数来处理 C websocket 程序中 Sec-WebSocket-Key 值的解析和散列。我让整个程序正常工作,但发现我有一堆 char* 没有指向的静态位置。正如您可能已经猜到的那样,这会导致一些内存问题并且需要修复。为了解决这个问题,我制作了大小为 100 的 char 并将 char* 指向它们。现在我从函数中返回的值不正确。有人可以告诉我我做错了什么。据我了解,这应该有效。仅供参考,我是自学成才的,但我对 C 的理解仍然存在巨大差距。
char* sock_handle_hash(struct sock_data *sockdat, int dataCount)
char EncodeHashbuff[100];
char key1buff[100];
char key2buff[100];
char key3buff[100];
char *EncodeHash = EncodeHashbuff;
char *key1 = key1buff;
char *key2 = key2buff;
char *key3 = key3buff;
unsigned char hash[SHA_DIGEST_LENGTH]; // this sets the length to the predefigned length in the SHA standard
char *testKey = "Sec-WebSocket-Key"; // this is the key for the key value pair of the hash
char *additionalHashData = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; // the magic string used in websockets
sockdat->buffer[dataCount] = '\0'; // null terminate the buffer
key1 = strtok(sockdat->buffer, "\n"); // brake up the data by new lines
key1 = strtok(NULL, "\n"); // skip the first line
while (key2 != NULL) //find the key to hash
key2 = strtok(NULL, ":"); //brake data into the key value pairs
key3 = strtok(NULL, "\n"); // go to next line
if(strcmp(key2, testKey) == 0) // if the correct key
if( key3[(strlen(key3)-1)] =='\r')
key3[(strlen(key3)-1)]='\0';
key3++;
char key4[200];
strcpy(key4, key3); // copy the string to the final key
strcat(key4, additionalHashData); // concat the magic websocket hash string
SHA1(key4, strlen(key4), hash); //Hash SHA1 to the correct reply value
EncodeHash = apssock_base64(hash, sizeof hash); // base 64 encode the value
break; //Stop looping
return EncodeHash; //success retrun the hashed value for the handshake
【问题讨论】:
什么是“大小为 100 的字符”?你的意思是char [100]
,即。 char
的数组?并查看How to Ask。
return EncodeHash;
也可以是return EncodeHashbuff;
,它返回函数范围内即将到期的自动变量的地址。因此,当调用者使用返回的地址时,未定义的行为。 Read this answer仔细。
仅供参考,除非 EncodeHash = apssock_base64(hash, sizeof hash);
动态分配生成的 base64 编码,我们从发布的代码中不知道,否则该代码路径同样会遭受类似的命运。如果它执行 dyna-alloc,它可能工作(至少它不会调用上面提到的 UB)。
谢谢 WhozCraig。这是一个非常有用的链接。仍然在解决这个问题。
【参考方案1】:
正如 WhozCraig 所说,我指的是无法保证存在的东西。为了解决这个问题,我在该行中添加了一个静态:
static char EncodeHashbuff[100];
【讨论】:
仅供参考:此解决方案不是线程安全的,因为内存将在线程之间共享。如果您的服务器是多线程的,这将失败。考虑更改函数的原型以接受要写入的缓冲区(这样,调用函数可以在堆栈上正常创建char
数组)。即char* sock_handle_hash(struct sock_data *sockdat, int dataCount, char * EncodeHash)
有趣。您能否提供有关该主题的更多信息的良好链接?谢谢。
有一些关于静态变量和线程安全的解释here 和here。至于将数据写入现有的char缓冲区,您可以看到一些答案herehere或here。以上是关于Websocket 密钥散列的主要内容,如果未能解决你的问题,请参考以下文章
使用 IAM API 密钥的 IBM Watson 语音转文本 WebSocket 授权
C# .NET Core websocket ssl 问题 - dh 密钥太小