首页 > 解决方案 > c# 服务器的 websocket 握手失败

问题描述

我尝试在 C# 中设置服务器端 Websocket,如https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers中所述,但是一旦我尝试连接它就会失败Error during WebSocket handshake: Incorrect 'Sec-WebSocket-Accept'

        public string ComputeWebSocketHandshakeSecurityHash(String secWebSocketKey) {
        const String MagicKEY = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
        String secWebSocketAccept = String.Empty;

        // 1. Combine the request Sec-WebSocket-Key with magic key.
        String ret = secWebSocketKey + MagicKEY;

        // 2. Compute the SHA1 hash
        SHA1 sha = new SHA1CryptoServiceProvider();
        byte[] sha1Hash = sha.ComputeHash(Encoding.UTF8.GetBytes(ret));

        // 3. Base64 encode the hash
        secWebSocketAccept = Convert.ToBase64String(sha1Hash);
        return secWebSocketAccept 
        };

该页面指出的示例dGhlIHNhbXBsZSBub25jZQ==应该导致s3pPLMBiTxaQ9kYGzzhZRbK+xOo=并且正在工作。

以下是 Chrome 客户端的示例标头:

请求标头:

        Accept-Encoding: gzip, deflate, br
        Accept-Language: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
        Cache-Control: no-cache
        Connection: Upgrade
        Host: localhost:4444
        Origin: https://localhost
        Pragma: no-cache
        Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
        Sec-WebSocket-Key: GW/l6VLlmjmmwZ2U6BMg7g==
        Sec-WebSocket-Protocol: plain
        Sec-WebSocket-Version: 13
        Upgrade: websocket
        User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)             AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36

响应标头:

        Connection: Upgrade
        Sec-WebSocket-Accept: RNBWSHjxgtG6/yEZKh/9U776A5U=
        Upgrade: WebSocket

很明显,接受密钥似乎与请求密钥不匹配,但为什么呢?以及为什么它以这种方式适用于 Mozilla ws 示例?

标签: c#hashencodingwebsocket

解决方案


我终于解决了这个问题。但正如它所指出的,它与上面的代码无关;这是按预期工作的。这总是无法连接的原因是传递给函数的错误键导致错误结果。(我将保留该帖子,以便其他人可以使用该代码创建哈希)。

在我的测试中,我尝试使用

sData = sReader.ReadLine();
        if (sData.StartsWith("Sec-WebSocket-Key: "))
        {
            string key = sData.Substring(19, sData.Length - 19).Trim(' ');
            String hashKey = ComputeSocketAcceptString(key);
            //Response here
        }

但是,从请求中提取代码的子字符串不正确。这导致函数计算出错误的哈希值。

对于所有正在搜索一些正确的请求/响应值进行测试的人,这里有一些:

Sec-WebSocket-Key: fAB2VSri/zcQdblwjKH9Ow== Sec-WebSocket-Accept: sGQcFOVDy7ctcd9TTk4Jr9vtXaQ=

Sec-WebSocket-Key: +YFXjHbEdHlvigafwh/Ixw== Sec-WebSocket-Accept: xdj5tRanzBYNvV31W6QIY5+mNjI=

Sec-WebSocket-Key: bNS0upBX5U6lICKLvFokUg== Sec-WebSocket-Accept: G66BkTwtxFeWMHaV7Dm/Cd4g+Rg=


推荐阅读