服务器端源码:

76号协议增加了加密字段

sec-websocket-key1

sec-websocket-key2

以及最后8个字节

服务器必须在握手信息之后发送回解密信息才能握手成功。

解密方式

key1 是 sec-websocket-key1 后面所有字节

key2 是 sec-websocket-key2 后面所有字节

part1 为 key1内除去所有的非数字字符后得到的数字 long型 / key1内空字符长度 int型

part2 为 key2内除去所有的非数字字符后得到的数字 long型 / key1内空字符长度 int型

part1 转换为byte[] byte1 (例:byte1 = {1,2,3,4})

part2 转换为byte[] byte2

byte1、byte2内值倒转(例:byte1 = {4,3,2,1})

byte3 是 客户端发送过来的最后8个字节

byte1、byte2、byte3 拼装为16个字节 byteKey[16]

byteKey[] 进行 MD5 加密 得 byteMD5[]

byteMD5[] 放置在握手协议最后端发送回去

C#  cs:

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Web.Security;
using System.IO;
namespace Room
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("服务器启动中...");
            IPEndPoint ipe = new IPEndPoint(IPAddress.Parse("192.168.1.80"), 2000);
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Bind(ipe);
            socket.Listen(60);
            Console.WriteLine("服务器启动完毕...");
            bool isfirst = true;
            bool run = true;
            try
            {
                Socket a = socket.Accept();
                while (run)
                {
                    byte[] bytes = new byte[1024];
                    int bytelength = a.Receive(bytes);
                    Console.WriteLine("接收完毕。");
                    #region websocket握手
                    if (isfirst)
                    {
                        string recStr = Encoding.UTF8.GetString(bytes, 0, bytelength);
                        string[] ss = recStr.Split(Environment.NewLine.ToCharArray());
                        string k1 = ss[10].Substring(20);
                        string k2 = ss[12].Substring(20);
                        byte[] last = new byte[8];
                        for (int i = 0; i < 8; i++)
                        {
                            last[i] = bytes[bytelength - 8 + i];
                        }
                        uint key1 = (uint)(long.Parse(FilterNonNumber(k1)) / FilterNonEmpty(k1).Length);
                        uint key2 = (uint)(long.Parse(FilterNonNumber(k2)) / FilterNonEmpty(k2).Length);
                        byte[] byteTemp1 = BitConverter.GetBytes(key1);
                        byte[] byteKey1 = new byte[4];
                        byte[] byteTemp2 = BitConverter.GetBytes(key2);
                        byte[] byteKey2 = new byte[4];
                        for (int i = 0; i < 4; i++)
                        {
                            byteKey1[i] = byteTemp1[3 - i];
                            byteKey2[i] = byteTemp2[3 - i];
                        }
                        MemoryStream ms = new MemoryStream();
                        ms.Write(byteKey1, 0, 4);
                        ms.Write(byteKey2, 0, 4);
                        ms.Write(last, 0, 8);
                        ms.Flush();
                        byte[] byteMs = ms.ToArray();
                        ms.Dispose();
                        MD5 md5 = MD5.Create();
                        byte[] md = md5.ComputeHash(byteMs);
                        MemoryStream ms1 = new MemoryStream();
                        string sendStr = "HTTP/1.1 101 WebSocket Protocol Handshake/r/nUpgrade: WebSocket/r/nConnection: Upgrade/r/nSec-WebSocket-Origin: null/r/nSec-WebSocket-Location: ws://192.168.1.80:2000//r/n/r/n";
                        byte[] temp = Encoding.UTF8.GetBytes(sendStr);
                        ms1.Write(temp, 0, temp.Length);
                        ms1.Write(md, 0, md.Length);
                        ms1.Flush();
                        byte[] byteSend = ms1.ToArray();
                        ms1.Dispose();
                        a.Send(byteSend, byteSend.Length, 0);
                        Console.WriteLine("发送完毕。");
                        isfirst = false;
                    }
                    #endregion
                    else
                    {
                        if (bytelength > 2)
                        {
                            string recStr = Encoding.UTF8.GetString(bytes, 1, bytelength - 2);
                            MemoryStream ms2 = new MemoryStream();
                            string strSend = "发送回去的是中文。";
                            byte[] byteSend = Encoding.UTF8.GetBytes(strSend);
                            ms2.WriteByte(0);
                            ms2.Write(byteSend, 0, byteSend.Length);
                            ms2.WriteByte(255);
                            ms2.Flush();
                            a.Send(ms2.ToArray());
                            ms2.Dispose();
                            if (recStr.Equals("exit"))
                            {
                                run = false;
                                Console.WriteLine("用户已退出。");
                            }
                            else
                            {
                                Console.WriteLine("接收到:" + recStr);
                            }
                        }
                        else
                        {
                            run = false;
                            Console.WriteLine("用户已退出。");
                        }
                    }
                }
                Console.ReadLine();
                a.Close();
                socket.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            finally
            {
                socket.Close();
            }
        }
        public static string FilterNonNumber(string str)
        {
            if (str == null)
            {
                return "";
            }
            char[] c = str.ToCharArray();
            StringBuilder sb = new StringBuilder();
            for (int i = 0, len = c.Length; i < len; i++)
            {
                if (char.IsNumber(c[i]))
                {
                    sb.Append(c[i]);
                }
            }
            return sb.ToString();
        }
        public static string FilterNonEmpty(string str)
        {
            if (str == null)
            {
                return " ";
            }
            char[] c = str.ToCharArray();
            StringBuilder sb = new StringBuilder();
            for (int i = 0, len = c.Length; i < len; i++)
            {
                if (c[i] == ' ')
                {
                    sb.Append(c[i]);
                }
            }
            if (sb.ToString().Length == 0)
            {
                return " ";
            }
            else
            {
                return sb.ToString();
            }
        }
    }
}

C# websocket Server 加密 76号协议的更多相关文章

  1. Microsoft SQL Server 数据库 错误号大全

    panchzh :Microsoft SQL Server 数据库 错误号大全0 操作成功完成. 1 功能错误. 2 系统找不到指定的文件. 3 系统找不到指定的路径. 4 系统无法打开文件. 5 拒 ...

  2. GIN+GORILLA=A GOLANG WEBSOCKET SERVER

    鉴于聊天已然成为大部分app的基础功能,而大部分app用户基数有没有辣么大,常用的聊天server架构如xmpp或者消息队列实现之类的用起来还挺麻烦的,有比较难跟网页端做交互,加之H5标准落地,所以w ...

  3. swoole之建立 websocket server

    一.代码部分 <?php /** * 为什么用WebSocket? * HTTP的通信只能由客户端发起 * * WebSocket 协议是基于TCP的一种新的网络协议.实现了浏览器与服务器全双工 ...

  4. 查看SQL SERVER 加密存储过程,函数,触发器,视图

    原文:查看SQL SERVER 加密存储过程,函数,触发器,视图 create  PROCEDURE sp_decrypt(@objectname varchar(50))ASbeginset noc ...

  5. 使用Jetty搭建Java Websocket Server,实现图像传输

    https://my.oschina.net/yushulx/blog/298140 How to Implement a Java WebSocket Server for Image Transm ...

  6. SQL Server 加密案例解析

    一.概述 加密是一种安全措施,有时候甚至是法律要求.作为攻破Windows系统的最后一道防线,通过加密可以保证在没有密钥的情况下获取备份或者物理介质变得毫无意义. 二.概念 加密层次结构 加密层次结构 ...

  7. SpringBoot报错:Failed to load ApplicationContext(javax.websocket.server.ServerContainer not available)

    引起条件: WebSocket+单元测试,单元测试报错! 解决方法: SpringBootTest增加webEnvironment参数. https://docs.spring.io/spring-b ...

  8. io.undertow.websockets.jsr.ServerWebSocketContainer cannot be cast to org.apache.tomcat.websocket.server.WsServerContainer

    Caused by: java.lang.ClassCastException: io.undertow.websockets.jsr.ServerWebSocketContainer cannot ...

  9. SQL SERVER孤立帐号的处理

    Step1:查询 Use KSHR_F23 Go exec sp_change_users_login @Action='Report' Go Step2:处理 Use KSHR_F23 Go exe ...

随机推荐

  1. comet

    comet 1.简介: 基于 HTTP长连接的“服务器推”技术,是一种新的 Web 应用架构,基于这种架构开发的应用中,服务器端会主动以异步的方式向客户端程序推送数据,而不需要客户端显式的发出请求.C ...

  2. postgreSQL初步使用总结

    一.安装 postgreSQL安装完成后会默认生成一个名为postgres的用户和一个名为postgres的数据库.可以使用自带的psql.exe工具来登录.其帮助信息如下 连接到本地的postgre ...

  3. HID高级攻击姿势:利用PowerShell脚本进行文件窃取

    0×01 引言 又到了期中考试了,我又要去偷答案了,一直发现远程下载运行exe的方式不太好,容易报毒所以这里打算用ps脚本. 0×02 关于HID HID是Human Interface Device ...

  4. 集合set的使用

    将无序对象储存在集合中 集合是类似于数组的一组对象,只是其中包含的项目是无序的(而数组是有序的).您通过枚举集合中的对象,或者将过滤器或测试应用到集合,来随机访问集合中的对象(使用 anyObject ...

  5. php大力力 [021节]mysql表名在mac下不能大写

    2015-08-27 php大力力021.mysql表名在mac下不能大写 刚才数据库里面,phpMyAdmin狂出错. Some errors have been detected on the s ...

  6. 偶遇makeblock

    上周出去吃饭在公交站牌上看到一家叫“创客工场”的公司在打招聘广告,当时在想这公司有钱啊,广告都打到这儿了,也没细想让韩总扫了一下他们的二维码,回来搜了一下这个公司,我靠,是做开源硬件的:再一看各种机器 ...

  7. 利用 Postfix 抵擋垃圾信

    reject_unknown_client               //add 20151117

  8. Android SoundPool.play方法的音量与系统音量的关系

    Android中播放音频,除了使用MediaPlayer,还可以使用SoundPool.SoundPool使用音效池的概念来管理多个短促的音效,对于需要短促的提示音的场景特别合适. 通常调用Sound ...

  9. android定时更新文件

    static变量在程序退出时不会清空的,除非系统内存不足以运行其他程序,才会清空.给SD卡上的文件过期时间.可以简单的在给文件命名时后面加个创建时间,在下次访问时判断是否需要更新.比如本来文件名是 i ...

  10. spring和redis的整合-超越昨天的自己系列(7)

    超越昨天的自己系列(7) 扯淡:  最近一直在慢慢多学习各个组件,自己搭建出一些想法.是一个涉猎的过程,慢慢意识到知识是可以融汇贯通,举一反三的,不过前提好像是研究的比较深,有了自己的见解.自认为学习 ...