Python之路(第三十四篇) 网络编程:验证客户端合法性
一、验证客户端合法性
如果你想在分布式系统中实现一个简单的客户端链接认证功能,又不像SSL那么复杂,那么利用hmac+加盐的方式来实现。
客户端验证的总的思路是将服务端随机产生的指定位数的字节发送到客户端,两边同时用hmac进行加密,然后对生成的密文进行比较,相同就是合法的客户端,不相同就是不合法的端户端。
示例代码
服务端
from socket import *
import hmac, os secret_key = b"nick" # 是指一个固定字符串的key def conn_auth(conn): # 定义函数认证客户端连接 print('开始验证新链接的合法性') # 打印提示
msg = os.urandom(32) # 随机生成一个32位的数
conn.sendall(msg) # 连接发送这个随机的数
h = hmac.new(secret_key, msg) # 传入要生成hmac摘要值的信息
digest = h.digest() # 生成一个hmac摘要
respone = conn.recv(len(digest)) # 接收回应,连接接收一个服务器端摘要的长度的信息
return hmac.compare_digest(respone, digest) # 比较客户端和服务端计算的摘要结果,一样则是True,不一样则是False def data_handler(conn, bufsize=1024): # 数据处理机函数(传入两个参数conn,和设置的默认大小)
if not conn_auth(conn): # 如果没有链接
print('该链接不合法,关闭') # 打印该链接不合法,关闭
conn.close() # 关闭链接
return
print('链接合法,开始通信') # 链接合法,开始通信
while True: # 循环为真
data = conn.recv(bufsize) # 接收数据
if not data: break # 如果没有数据则打断
conn.sendall(data.upper()) # 链接发送数据 def server_handler(ip_port, bufsize, backlog=5): # 服务器处理机ip和端口,设置大小
'''
只处理链接
:param ip_port:
:return:
'''
tcp_socket_server = socket(AF_INET, SOCK_STREAM) # 实例化一个tcp的套接字
tcp_socket_server.bind(ip_port) # 绑定ip端口
tcp_socket_server.listen(backlog) # 监听
while True: # 循环为真
conn, addr = tcp_socket_server.accept() # 接收链接和地址
print('新连接[%s:%s]' % (addr[0], addr[1])) # 打印新连接ip和端口
data_handler(conn, bufsize) # 调用数据处理机函数 if __name__ == '__main__':
ip_port = ('127.0.0.1', 9999)
bufsize = 1024
server_handler(ip_port, bufsize)
客户端
from socket import *
import hmac, os secret_key = b'nick' # 设置一个字符串key def conn_auth(conn): # 定义一个客户验证到服务器端的链接
'''
验证客户端到服务器的链接
:param conn:
:return:
'''
msg = conn.recv(32) # 接受一个32位的信息
h = hmac.new(secret_key, msg)
digest = h.digest() # 得到一个摘要值
conn.sendall(digest) # 发送这个摘要 def client_handler(ip_port, bufsize=1024):
tcp_socket_client = socket(AF_INET, SOCK_STREAM) # 创建一个tcp套接字的对象
tcp_socket_client.connect(ip_port) conn_auth(tcp_socket_client) # 执行验证 while True:
data = input('>>: ').strip() # 输入内容
if not data: continue # 如果没有内容则跳过
if data == 'quit': break tcp_socket_client.sendall(data.encode('utf-8')) # 发送数据
respone = tcp_socket_client.recv(bufsize) # 接收数据
print(respone.decode('utf-8')) # 打印接收的数据
tcp_socket_client.close() # 关闭这个套接字 if __name__ == '__main__':
ip_port = ('127.0.0.1', 9999)
bufsize = 1024
client_handler(ip_port, bufsize)
Python之路(第三十四篇) 网络编程:验证客户端合法性的更多相关文章
- Python之路(第三十二篇) 网络编程:udp套接字、简单文件传输
一.UDP套接字 服务端 # udp是无链接的,先启动哪一端都不会报错 # udp没有链接,与tcp相比没有链接循环,只有通讯循环 server = socket.socket(socket.AF_I ...
- Python之路(第三十六篇)并发编程:进程、同步异步、阻塞非阻塞
一.理论基础 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一.操作系统的其他所有内容都是围绕进程的概念展开的. 即使可以利用的cpu只有一个(早期的 ...
- Python之路(第三十八篇) 并发编程:进程同步锁/互斥锁、信号量、事件、队列、生产者消费者模型
一.进程锁(同步锁/互斥锁) 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 例 ...
- Python之路(第三十五篇) 并发编程:操作系统的发展史、操作系统的作用
一.操作系统发展史 第一阶段:手工操作 —— 真空管和穿孔卡片 第一代之前人类是想用机械取代人力,第一代计算机的产生是计算机由机械时代进入电子时代的标志,从Babbage失败之后一直到第二次世界大 ...
- Python之路【第十四篇】:AngularJS --暂无内容-待更新
Python之路[第十四篇]:AngularJS --暂无内容-待更新
- Python之路【第二十四篇】:Python学习路径及练手项目合集
Python学习路径及练手项目合集 Wayne Shi· 2 个月前 参照:https://zhuanlan.zhihu.com/p/23561159 更多文章欢迎关注专栏:学习编程. 本系列Py ...
- Python之路【第二十四篇】Python算法排序一
什么是算法 1.什么是算法 算法(algorithm):就是定义良好的计算过程,他取一个或一组的值为输入,并产生出一个或一组值作为输出.简单来说算法就是一系列的计算步骤,用来将输入数据转化成输出结果. ...
- Python之路【第十四篇】前端补充回顾
布局和事件 1.布局 首先看下下面的图片: 上面的内容都是居中的,怎么实现这个效果呢,第一种方法是通过float的方式,第二种是通过“div居中的方式” 第一种方式不在复述了,直接看第二种方式: 1. ...
- 【Python之路】第十四篇--jQuery
jquery简介 1.jquery是什么 ☛ 参考用法 jQuery由美国人John Resig创建,至今已吸引了来自世界各地的众多 javascript高手加入其team. jQuery ...
随机推荐
- zk hdfs hadoop yarn hive 学习笔记
如图
- 将String类型的json字符串转换成java对象
1,import com.fasterxml.jackson.databind.ObjectMapper; ObjectMapper mapper = new ObjectMapper(); Mycl ...
- 201772020113 李清华《面向对象程序设计(java)》第十五周学习总结
1.实验目的与要求 (1) 掌握Java应用程序的打包操作: (2) 了解应用程序存储配置信息的两种方法: (3) 掌握基于JNLP协议的java Web Start应用程序的发布方法: (5) 掌握 ...
- 《深入理解java虚拟机》读书笔记——垃圾收集与内存分配策略
可回收判定两种算法 引用计数法(Reference Counting):引用为0时可回收. 可达性分析法(Reachability Analysis): 从GCRoots对象到这个对象不可达. GCR ...
- mezzanine的breadcrumb
page_menu tag为什么能渲染出当前页的面包屑路径??靠的是request的page对象,要是page的自己或是它的的祖先才渲染,是根据page的属性page.is_current_or_as ...
- java面试题复习(二)
//我又回来了 11.数组有没有length()方法?String有没有length()方法? 数组只有length属性,String有length()方法.注意:JavaScript获取字符串长度使 ...
- Go 语言 map (映射)
1.Go 语言中 map 的定义及初始化: map[Key_Type]Value_Type scence := make(map[string]int) 2.Go 语言的遍历: scene := ma ...
- sql server 新语法 收藏
1.行转列 PIVOT函数,行转列,列转换UNPIVOT select * from ShoppingCart as C PIVOT(count(TotalPrice) FOR [Week] IN([ ...
- Springboot项目读取resource下的静态资源方法
如果按相对路径直接读会定位到target下,因为springboot打包后读到这里 如果做单元测试的话是找不到文件的 File jsonFile = ResourceUtils.getFile(&qu ...
- UI设计篇·入门篇·简单动画的实现,为布局设置动画,用XML布置布局动画
不仅仅控件可以设置动画,一个布局也可以设置动画, 当给一个布局设置了动画的时候,这个布局里所包含的控件都会依赖执行这些动画. 为布局设置动画的实现步骤: 1.新建一个动画,设置需要实现的形式 2.新建 ...