websocket的加密和解密

补充个小知识点:按位与运算

按位与运算是同位都为1才为1,有一个不为1就是0

 

websocket_hand

 1 import socket, base64, hashlib
 2 import websocket_jiemi
 3 import websocket_jiami
 4 
 5 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 6 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 7 sock.bind(('127.0.0.1', 9527))
 8 sock.listen(5)
 9 # 获取客户端socket对象
10 conn, address = sock.accept() # 阻塞
11 
12 # 获取客户端的【握手】信息
13 data = conn.recv(2048)
14 print(data)
15 
16 
17 """
18 b'
19 GET / HTTP/1.1\r\n
20 Host: 127.0.0.1:9527\r\n
21 Connection: Upgrade\r\n
22 Pragma: no-cache\r\n
23 Cache-Control: no-cache\r\n
24 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36\r\n
25 Upgrade: websocket\r\n
26 Origin: http://localhost:63342\r\n
27 Sec-WebSocket-Version: 13\r\n
28 Accept-Encoding: gzip, deflate, br\r\n
29 Accept-Language: zh-CN,zh;q=0.9\r\n
30 Sec-WebSocket-Key: tPWfDfGthkhhqfY4ZdT1yQ==\r\n
31 Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n\r\n'
32 """
33 #
34 # # magic string为:258EAFA5-E914-47DA-95CA-C5AB0DC85B11
35 magic_string = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
36 #
37 #
38 def get_headers(data):
39     header_dict = {}
40     header_str = data.decode("utf8")
41     for i in header_str.split("\r\n"):
42         if str(i).startswith("Sec-WebSocket-Key"):
43             header_dict["Sec-WebSocket-Key"] = i.split(":")[1].strip()
44 
45     return header_dict
46 
47 headers = get_headers(data)  # 提取请求头信息
48 
49 # # 对请求头中的sec-websocket-key进行加密
50 
51 #
52 value = headers['Sec-WebSocket-Key'] + magic_string  # jtl/vockZ8GRyadFVeiUTA==258EAFA5-E914-47DA-95CA-C5AB0DC85B11
53 print(value)
54 sha1_value = hashlib.sha1(value.encode('utf-8')).digest()
55 print("sha1_value",sha1_value)
56 ac = base64.b64encode(sha1_value)
57 print("ac",ac)
58 # ac  - sha1(sec+magic) - base64
59 response_tpl = "HTTP/1.1 101 Switching Protocols\r\n" \
60                "Upgrade:websocket\r\n" \
61                "Connection: Upgrade\r\n" \
62                "Sec-WebSocket-Accept: %s\r\n" \
63                "WebSocket-Location: ws://127.0.0.1:9527\r\n\r\n"
64 
65 response_str = response_tpl % (ac.decode('utf-8'))
66 # 响应【握手】信息
67 conn.send(response_str.encode("utf8"))
68 
69 while True:
70     msg = conn.recv(8096)
71     msg = websocket_jiemi.websocket_jiema(msg)
72 
73     # conn.send("123123123123".encode("utf8"))
74     send_str = websocket_jiami.jiami("hello".encode("utf8"))
75     print(send_str)
76     conn.send(send_str)

 

websocket_jiami

 1 import struct
 2 # msg_bytes = "哎呀妈呀脑瓜疼".encode("utf8")
 3 def jiami(msg_bytes):
 4     token = b"\x81"
 5     length = len(msg_bytes)
 6 
 7     if length < 126:
 8         token += struct.pack("B", length) # \x85$
 9     elif length == 126:
10         token += struct.pack("!BH", 126, length)
11     else:
12         token += struct.pack("!BQ", 127, length)
13 
14     msg = token + msg_bytes
15 
16     return msg

 

websocket_jiemi

 1 # b'\x81\x83\xceH\xb6\x85\xffz\x85'
 2 
 3 hashstr = b'\x81\x85$\xcb>\x14L\xaeRxK'
 4 # b'\x81
 5 # \x85$
 6 # \xcb>\x14L\xaeRxK\xcb>\x14L\xaeRxK\xcb>\x14L
 7 # \xaeRxK\xcb>\x14L\xaeRxK
 8 # \xcb>\x14L\xaeRxK\xcb>\x14L\xaeRxK\xcb>\x14L\xaeRxK\xcb>\x14L\xaeRxK\xcb>\x14L\xaeRxK\xcb>\x14L\xaeRxK\xcb>\x14L\xaeRxK\xcb>\x14L\xaeRxK'
 9 
10 # 将第二个字节也就是 \x83 第9-16位 进行与127进行位运算
11 
12 def websocket_jiema(hashstr):
13     print(hashstr[1])
14     payload = hashstr[1] & 127
15     print(payload)
16 
17     if payload == 127:
18         extend_payload_len = hashstr[2:10] # 834473503
19         mask = hashstr[10:14]
20         decoded = hashstr[14:]
21     # 当位运算结果等于127时,则第3-10个字节为数据长度
22     # 第11-14字节为mask 解密所需字符串
23     # 则数据为第15字节至结尾
24     #
25 
26     # b'\x81
27     # \x85$    126
28     # \xcb>\x14L 120
29     # \xaeRxK\xcb>\x14L\xaeRxK
30     # \xcb>\x14L\xaeRxK\xcb>\x14L\xaeRxK \xcb>\x14L\xaeRxK\xcb>\x14L\xaeRxK\xcb>\x14L\xaeRxK\xcb>\x14L\xaeRxK\xcb>\x14L\xaeRxK\xcb>\x14L\xaeRxK\xcb>\x14L\xaeRxK\xcb>\x14L\xaeRxK'
31 
32 
33     if payload == 126:
34         extend_payload_len = hashstr[2:4]
35         mask = hashstr[4:8]
36         decoded = hashstr[8:]
37     # 当位运算结果等于126时,则第3-4个字节为数据长度
38     # 第5-8字节为mask 解密所需字符串
39     # 则数据为第9字节至结尾
40     #
41     #   b'\x81
42     # \x85$ 5 len数据长度
43     # \xcb>\x14L\xaeRxK'
44 
45     if payload <= 125:
46         extend_payload_len = payload
47         mask = hashstr[2:6]
48         decoded = hashstr[6:]  # 5
49 
50     # 当位运算结果小于等于125时,则这个数字就是数据的长度
51     # 第3-6字节为mask 解密所需字符串
52     # 则数据为第7字节至结尾
53     #
54     str_byte = bytearray()
55     #
56     for i in range(len(decoded)):
57         byte = decoded[i] ^ mask[i % 4]
58         str_byte.append(byte)
59     #
60     return str_byte.decode("utf8")

 

my_socket

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8 
 9 </body>
10 <script>
11     var ws = new WebSocket("ws://127.0.0.1:9527")
12     ws.onmessage = function (data) {
13         console.log(data.data)
14 
15     }
16 </script>
17 </html>

 

转载于:https://www.cnblogs.com/Roc-Atlantis/p/9892890.html

最新版本,请从Simpleflow官方站点下载 http://www.simpleflow.com.cn Simpleflow V20090103 基于Domino的工作流套件 Mail: Simpleflow@163.com QQ: 935139121 BLog: http://blog.csdn.net/simpleflow V2009预览: http://blog.csdn.net/simpleflow/archive/2008/12/13/3509566.aspx 1.关于License,此版本为20用户免费版.仅用于评估与学习,但没有时间限制 如果对Simpleflow认可,可以免费申请100用户注册码. 申请注册码方法需要提供以下信息 1.公司名称 2.公司地址 3.公司电话 4.申请人 5.申请人手机 6.服务器名(FullName) 7.申请人数 发送到Simpleflow@163.com 我们会在最短时间内给您回复您的注册码. 2.关于套件组成 1.Application.nsf 流程运行应用库(必需)(CS/BS) 2.Process.nsf 流程定义库(必需)(仅CS) 3.Organization.nsf 流程组织库(CS/BS) 4.Outofoffice.nsf 外出代理授权库(CS/BS) 5.Archive.nsf 流程归档库样例(CS/BS) 6.Log.nsf 流程运行日志库(CS/BS) 7.Names_Ext.nsf 辅助目录库(CS/BS) 注:所有Profile设置,均在CS进行. 3.关于自带样例 1.非生产采购申请 一个简单实现的采购申请,业务流程不一定具有代表性.仅供参考 实现功能包括: A.BSCS混合驱动 B.标准化拆分与合并(执行委员会节点,按参与者拆分) 说明:此流程除需要创建相应表单外,不需要写任何LS代码 2.收文流程 实现功能包括: A.BSCS混合驱动 B.自定义的拆分与合并(部门承办,承办完成等待合并节点,自定义合并处理,针对指定栏位进行处理) 3.督办流程 A.BS驱动.其它类似收文 4.关于ACL 所有数据库的管理员请设置为管理员级别,并请设置[SysAdmin]角色 1.Application.nsf Default是作者[创建,删除文档,写公共文档] 如果流程支持拆分与合并,则同时需要 [复制与粘贴文档]权限 2.Process.nsf Default是读者 3.Organization.nsf Default作者(如果扩展该库功能的话,请赋予相应的写权限) 4.Outofoffice.nsf Default是作者[创建删除] 5.Log.nsf Default是作者[创建] 6.Archive.nsf Default是作者[创建] 7.Names_Ext Default是作者[创建] 说明ACL设置需要根据具体情况来设置,这里并不是给出标准设置,仅供参照. 如果哪位发现有安全性漏洞,请反馈给Simpleflow@163.com.谢谢支持. 5.关于设置 每个数据库请用[SysAdmin]角色的用户在CS登陆后,在[系统管理]里进行[系统设定] 系统设定主要包括数据库路径设定,不需要多讲 6.如何新建流程定义 http://blog.csdn.net/simpleflow/archive/2008/01/24/2062579.aspx http://blog.csdn.net/simpleflow/archive/2008/01/24/2062850.aspx 流程定义库已作过部分升级,但仍可参照 7.如何新建一个流程实例 1.CS 在导航帧的左下角,下拉框选择后启动 2.BS 页面右帧靠近顶部的绿色小图标 8.咨询与联系 如有疑惑或需要支持,请通过Mail联系我,我会及时进行回复,并整理一些普遍关心的问题发布到Blog上. 9.谢谢支持. 欢迎大家提出不管支持也好反对也好的意见.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值