一、验证客户端合法性

如果你想在分布式系统中实现一个简单的客户端链接认证功能,又不像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之路(第三十四篇) 网络编程:验证客户端合法性的更多相关文章

  1. Python之路(第三十二篇) 网络编程:udp套接字、简单文件传输

    一.UDP套接字 服务端 # udp是无链接的,先启动哪一端都不会报错 # udp没有链接,与tcp相比没有链接循环,只有通讯循环 server = socket.socket(socket.AF_I ...

  2. Python之路(第三十六篇)并发编程:进程、同步异步、阻塞非阻塞

    一.理论基础 进程的概念起源于操作系统,是操作系统最核心的概念,也是操作系统提供的最古老也是最重要的抽象概念之一.操作系统的其他所有内容都是围绕进程的概念展开的. 即使可以利用的cpu只有一个(早期的 ...

  3. Python之路(第三十八篇) 并发编程:进程同步锁/互斥锁、信号量、事件、队列、生产者消费者模型

    一.进程锁(同步锁/互斥锁) 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 例 ...

  4. Python之路(第三十五篇) 并发编程:操作系统的发展史、操作系统的作用

    一.操作系统发展史 第一阶段:手工操作 —— 真空管和穿孔卡片 ​ 第一代之前人类是想用机械取代人力,第一代计算机的产生是计算机由机械时代进入电子时代的标志,从Babbage失败之后一直到第二次世界大 ...

  5. Python之路【第十四篇】:AngularJS --暂无内容-待更新

    Python之路[第十四篇]:AngularJS --暂无内容-待更新

  6. Python之路【第二十四篇】:Python学习路径及练手项目合集

      Python学习路径及练手项目合集 Wayne Shi· 2 个月前 参照:https://zhuanlan.zhihu.com/p/23561159 更多文章欢迎关注专栏:学习编程. 本系列Py ...

  7. Python之路【第二十四篇】Python算法排序一

    什么是算法 1.什么是算法 算法(algorithm):就是定义良好的计算过程,他取一个或一组的值为输入,并产生出一个或一组值作为输出.简单来说算法就是一系列的计算步骤,用来将输入数据转化成输出结果. ...

  8. Python之路【第十四篇】前端补充回顾

    布局和事件 1.布局 首先看下下面的图片: 上面的内容都是居中的,怎么实现这个效果呢,第一种方法是通过float的方式,第二种是通过“div居中的方式” 第一种方式不在复述了,直接看第二种方式: 1. ...

  9. 【Python之路】第十四篇--jQuery

    jquery简介 1.jquery是什么       ☛ 参考用法 jQuery由美国人John Resig创建,至今已吸引了来自世界各地的众多 javascript高手加入其team. jQuery ...

随机推荐

  1. CSS : color and unit

    Color: CSS中定义颜色使用十六进制(hex)表示法为红,绿,蓝的颜色值结合.可以是最低值是0(十六进制00)到最高值是 255(十六进制FF).3个双位数字的十六进制值写法,以#符号开始部分颜 ...

  2. Windows下pip 离线包安装

    pip在线安装十分方便,有时候某些服务器并没有直接联网,需要下载好安装包上传到服务器上进行安装,不经常用,还是有点小麻烦的. 安装Python之后,将下载好的安装包包放在Python安装的根目录下使用 ...

  3. mac下新建txt文本快捷方式.md

    转:127.0.0.1:47873/help/0-436/ms.help?method=page&id=A38C5670-BA28-44F3-BD5B-FCB46880E904&pro ...

  4. c++ 使用模板按类型统计stl多维容器中元素的数量

    struct ItemCounter{template<typename T1, typename T2, typename = typename std::enable_if<!std: ...

  5. kruskal(拓展)

    kruskal是最小生成树的一种做法,即严格按照贪心思想将边从小到大排序,一个一个枚举能不能加入图中,知道生成一棵树,显然树为最小树. 鄙人觉得kruskal做法远不止如此,那种严格从小到大选边的做法 ...

  6. IDEA中MAVEN项目Dependency not found 问题

    STEP1: 更新IDEA保存的仓库索引.操作步骤File->Setting->Maven->Repositories->Update.dependecy not found问 ...

  7. html页面通过http访问mysql数据库中的内容,实现用户登录的功能

    需求: 通过html编写用户登录页面,页面内容包括用户名.密码和登录按钮,点击登录后访问login.php文件,使用按钮默认的submit提交用户名和密码,在login.php中访问mysql数据库, ...

  8. Win10 for Docker 安装 K8S

    win 10 docker安装K8S中遇见的一些问题,记录下来方便自己以后避免采坑. 安装步骤: 1.安装Docker for windows.在docker官方下载,然后傻瓜式安装. 安装成功以后再 ...

  9. spark on yarn 内存分配

    Spark On YARN内存分配 本文主要了解Spark On YARN部署模式下的内存分配情况,因为没有深入研究Spark的源代码,所以只能根据日志去看相关的源代码,从而了解“为什么会这样,为什么 ...

  10. 操作CSS样式公共方法库

    项目中常用的一些方法,我们都封装到公共方法库 let utils = (function () { //=>获取元素的样式 let getCss = function (curEle, attr ...