C#实现WSS服务器遇SSLStream解密失败,请求代码排查
问题原因及修复方案
1. 证书密钥存储配置错误
你使用X509KeyStorageFlags.UserKeySet加载证书,但服务器进程通常运行在系统账户(如Local System)下,无法访问用户密钥容器,会导致证书私钥加载异常,最终引发SSL解密失败。
修复代码:
var certificate = new X509Certificate2( "C:\\Users\\Administrator\\Documents\\mypfx.pfx", "1234", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable );
2. 未实现WebSocket握手流程
WebSocket连接需要先完成HTTP升级握手,而非SSL握手后直接读取字节。客户端会发送带Upgrade: websocket头部的HTTP请求,服务器必须返回规范的101响应,否则客户端会断开连接,导致SSLStream读取时抛出异常。
修复代码:
在SSL握手后添加握手处理逻辑:
// 读取客户端HTTP升级请求 StreamReader reader = new StreamReader(stream); string requestLine = reader.ReadLine(); string webSocketKey = string.Empty; string line; while ((line = reader.ReadLine()) != null) { if (line.StartsWith("Sec-WebSocket-Key:")) { webSocketKey = line.Split(':')[1].Trim(); break; } } // 生成握手响应的AcceptKey const string webSocketGuid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; string combinedKey = webSocketKey + webSocketGuid; byte[] hashBytes = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(combinedKey)); string acceptKey = Convert.ToBase64String(hashBytes); // 发送握手响应 string response = $"HTTP/1.1 101 Switching Protocols\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n" + $"Sec-WebSocket-Accept: {acceptKey}\r\n\r\n"; StreamWriter writer = new StreamWriter(stream); writer.Write(response); writer.Flush(); // 握手完成后,再开始读取WebSocket帧 while (true) { int i = stream.ReadByte(); if (i == -1) break; // 后续需按WebSocket帧格式解析数据,此处仅作示例 }
3. 客户端未信任自签名证书
浏览器默认拒绝自签名证书,会直接阻断WSS连接。需手动将证书导入浏览器的「受信任的根证书颁发机构」,否则客户端无法完成SSL握手。
内容的提问来源于stack exchange,提问作者russb
相关产品推荐
相关产品推荐

