hashlib(hmac)进阶之client跟server交互
首先我还是要强调不管任何相同的字符串通过hashlib加密之后都会产生相同的32位字符串,这个是日常Web中常用的加密算法如果我的client发送一个请求过来我server接受到后就要对该密码进行判断,正常的流程是我需要把client端发送过来的请求转换成hashlib格式的字符串跟我存在数据库中的字符串进行对比做判断,当前我也可以在这些字符串加密前加盐(key)
以下是我的基础的server代码
代码解析:
首先我们需要明白Tcp下的服务端的7步曲
1.实例化socket对象
sk = socket.socket()
2绑定对应的服务器IP地址以及对外开放的端口
sk.bind(("127.0.0.1",8888))
3启动监听等待用户访问
sk.listen()
4建立tcp下的基本连接协议
conn,addr = sk.accept()
#5通讯的逻辑
rse = conn.recv(1024)#指定接收1024的字符串
conn.send("相信你自己就是最牛逼的哪一个".decode("utf-8"))
#6四次挥手断开连接
conn.close()
#7退还端口
sk.close()
这就是基础的服务端的代码
下面我要对服务端进行改造改造代码如下
# ### 服务器
import socket
import hmac
import os def auth(conn,secret_key):
# 随机的32位二进制字节流
res = os.urandom(32)
# 把res发送给对方的服务器
conn.send(res)
# 用hmac加密字符串
hm = hmac.new(secret_key.encode(),res)
# 通过hexdigest返回32长度的十六进制字符串
res_server = hm.hexdigest()
print(res_server) # 接受客户端发过来的加密后的字符串
res_cli = conn.recv(1024).decode("utf-8") if res_server == res_cli:
print("该用户是合法的链接请求")
return True
else:
print("该用户是非法的链接请求")
return False # 创建对象
sk = socket.socket()
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sk.bind( ("127.0.0.1",9001) )
sk.listen()
conn,addr = sk.accept() # 收发数据的逻辑
secret_key = "ig不牛逼"
# 调用函数,验证权限
res = auth(conn,secret_key)
# 如果验证的结果是真的,就处理用户发送过来的请求,假的直接断开链接
if res:
print(conn.recv(1024).decode("utf-8")) conn.close()
sk.close()
注os.urondom()是os模块下的一种方法,随机产生指定位数的随机2进制字节流
此时我对收发逻辑做了一定的处理下面我为为我写的auth代码进行解析
自定义一个auth权限函数,该函数需要2个变量conn(客户端返回服务端的端口对象或链接对象),secret_key(盐也就是我要key )
1 在auth里面我随机生成了一个指定32位随机2进制字节流os.urandom(32)
2 我需要把我服务端生成的32位随机季节流发送给服务端 conn.send(res)
3 用hmac加密hmac.new(secret_key.encode(),res) 俩个参数(一个是我需要加入的盐,另外一个是我生成的32位随机2进制流)
通过hmac的加密我会产生一个新的数据流 而这个数据流与客户端发送过来的数据流是一致的话那么我就可以认为此时的数据所对应的结果是一致的密码匹配成功
4 接受客户端加密后的密码串进行反解
5 验证客户端的加密是否与服务端的加密内容是否一致
6返回判断的内容
如果auth判断的结果是Ture那么我就直接给客户端返回这个登录状态登录成功
否则则给客户端返回一个登录失败的状态
关闭连接
退还端口
客户端的代码
是首先需要对socket进行引入
import socket
sk = socket.socket()#实例化socket对象
sk .connect(("127.0.0.1",8888))#指定相对应的服务器访问
sk.send("相信你自己是最牛逼的哪一个".encode())#对服务器发送请求
res = sk.recv(1024).decode("utf-8")接受服务端给我返回的消息
sk.close()#退还端口
下面我队我客户端的代码进行优化
# ### 客户端
import socket
import hmac def auth(sk,secret_key):
# 收发数据的逻辑
msg = sk.recv(32)
# 把key 和 msg 扔到new当中,进行加密
hm = hmac.new(secret_key.encode(),msg)
# 通过hexdigest把加密后的结果返回出来
res_cli = hm.hexdigest()
print(res_cli)
# 把加密好的字符串在发送回原服务器
sk.send(res_cli.encode()) sk = socket.socket()
sk.connect( ("127.0.0.1",9001) ) secret_key = "ig不牛逼"
# 调用函数,验证权限
auth(sk,secret_key)
# 向服务器发出下载的请求
sk.send(b"download") # 关闭链接
sk.close()
首先基于原始的client与服务端的通信下我对我的收发数据的逻辑进行了改造
自定义一个auth权限函数,该函数需要2个变量sk(客户端要与服务端的端口对象或链接对象),secret_key(盐也就是我要key )
1 我需要把我客户端接受服务端给我发送的32位随机2进制流 sk.recv(32)
3 用hmac加密hmac.new(secret_key.encode(),res) 俩个参数(一个是我需要加入的盐,另外一个是我生成的32位随机2进制流)
通过hmac的加密我会产生一个新的数据流 而这个数据流我会发送给服务端数,如果我客户端收缩加密的字节流与服务端加密的是一致的话我会得到服务端的校验判定
sk.close()#退还端口
传统简易的server与client登录验证交互
server代码
基于上面的代码我现在扩展模拟到数据库中取出我的账号以及密码并且对服务端发送过来的账户密码进行验证,如果验证成功我就给客户端返回登录状态
以下是代码
# ### 服务端
import hashlib
import socket
import json def get_md5_code(usr,pwd):
# 将用户名作为加密的盐key
hm = hashlib.md5(usr.encode())
hm.update(pwd.encode())
res = hm.hexdigest()
return res sk = socket.socket()
sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
sk.bind( ("127.0.0.1",9000) )
sk.listen()
conn,addr = sk.accept() # 处理收发数据的逻辑
# 先接受二进制字节流 -> 字符串
msg = conn.recv(1024).decode()
print(msg,type(msg))
# 把字符串 -> 字典
dic = json.loads(msg)
print(dic,type(dic)) # 标识符,默认False
sign = False
with open("userinfo.txt",mode="r",encoding="utf-8") as fp:
for line in fp:
usr,pwd = line.strip().split(":")
if usr == dic["username"] and pwd == get_md5_code(dic["username"],dic["password"]):
# 登陆成功 返回状态吗为1
res = {"code":1}
res_msg = json.dumps(res).encode()
conn.send(res_msg)
# 如果登录成功,默认改成True
sign = True
break if sign == False:
#登录失败,返回状态码为0
res = {"code":0}
conn.send(json.dumps(res).encode()) # 四次挥手
conn.close()
# 退还端口
sk.close()
代码解析
def get_md5_code(usr,pwd):
# 将用户名作为加密的盐key
hm = hashlib.md5(usr.encode())
hm.update(pwd.encode())
res = hm.hexdigest()
return res
这里代码的主要作用是把用户名作为盐(key),pwd作为要加密的字符串
返回的是一个加盐(key)后的随机32位字符串,当我收到客户端的数据后需要经过json 字符串的反解后得到的一个字典,该字典包含了密码以及用户名的一种数据
此时我需要把字典的用户名以及密码拿出来做加密后跟数据库所存的随机字符串做比对,如果比对成功那么我就会给客户端返回一个状态反之给客户端返回一个否定的状态
下面我要介绍我的客户端的代码
# ### 客户端
import socket
import json
sk = socket.socket()
sk.connect( ("127.0.0.1",9000) ) usr = input("请输入您的账户:")
pwd = input("请输入您的密码:")
dic = {"username":usr,"password":pwd,"operate":"login"}
# 返回json格式的字符串
res = json.dumps(dic)
# 在把json字符串转换成字节流
bytes_msg = res.encode()
# 发送给服务端
sk.send(bytes_msg) # 接受服务端发送回来的数据
res_msg = sk.recv(1024).decode()
# 把字符串变成字典
dic_code = json.loads(res_msg) if dic_code["code"]:
print("恭喜你,登陆成功")
else:
print("抱歉,登陆失败") # 关闭链接
sk.close()
首先在客户端中我要生成一个字典,字典里面包含了我的账户以及密码名我通过json下的dumps强制把字典转换为json类型的字符串,通过这个字符串我直接发给服务端,让服务端帮我操作,如果匹配成功那么我就返回一个已经登录的状态,反之登录失败
hashlib(hmac)进阶之client跟server交互的更多相关文章
- 深入浅出 Redis client/server交互流程
综述 最近笔者阅读并研究redis源码,在redis客户端与服务器端交互这个内容点上,需要参考网上一些文章,但是遗憾的是发现大部分文章都断断续续的非系统性的,不能给读者此交互流程的整体把握.所以这里我 ...
- Python——常用模块(time/datetime, random, os, shutil, json/pickcle, collections, hashlib/hmac, contextlib)
1.time/datetime 这两个模块是与时间相关的模块,Python中通常用三种方式表示时间: #时间戳(timestamp):表示的是从1970年1月1日00:00:00开始按秒计算的偏移量. ...
- [从源码学设计]蚂蚁金服SOFARegistry 之 如何与Meta Server交互
[从源码学设计]蚂蚁金服SOFARegistry 之 如何与Meta Server交互 目录 [从源码学设计]蚂蚁金服SOFARegistry 之 如何与Meta Server交互 0x00 摘要 0 ...
- UDP编程中client和server中使用recvfrom和sendto的区别
client中: sendto(sfd,buf,strlen(buf),0,(struct sockaddr *)&saddr,len); recvfrom(sfd,buf ...
- tmux protocol version mismatch (client 7, server 6)
$ tmux attach protocol version mismatch (client 7, server 6) $ pgrep tmux 3429 $ /proc/3429/exe atta ...
- New full duplex HTTP tunnel implementation (client and server)
https://issues.jboss.org/browse/NETTY-246?page=com.atlassian.jirafisheyeplugin:fisheye-issuepanel —— ...
- jvm的client和server
最近研究c++代码调用java的jar,发现64位的下的jvm在server路径,而32位的jvm则存在client路径下面,于是十分好奇,查了下,这里做个记录 JVM Server模式与client ...
- Android简单的聊天室开发(client与server沟通)
请尊重他人的劳动成果.转载请注明出处:Android开发之简单的聊天室(client与server进行通信) 1. 预备知识:Tcp/IP协议与Socket TCP/IP 是Transmission ...
- 【Python】 hash值计算 hashlib & hmac
hashlib & hmac *不是很清楚能不能把这种hash值取样算法称之为加密,但是似乎好像也是这么说的哈(非科班出身的野路子就是没这种基本知识的) ■ 基本用法 hashlib支持MD5 ...
随机推荐
- centos 下创建本地镜像源,结合 nginx
1. 创建同步文件 参考清华的Centos源,配置同步文件.https://mirrors.tuna.tsinghua.edu.cn/help/centos/ [root@localhost cent ...
- php实现图片下载
download.php下载代码 <?php //获取要下载的文件名 $filename = $_GET['filename']; //设置头信息 header('Content-Disposi ...
- 201871010116-祁英红《面向对象程序设计(java)》第四周学习总结
博文正文开头格式:(2分) 项目 内容 <面向对象程序设计(java)> https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://ww ...
- MongoDB Java(七)
在 Java 程序中如果要使用 MongoDB,你需要确保已经安装了 Java 环境及 MongoDB JDBC 驱动. mongodb-driver jar 下载地址:http://central. ...
- 《阿里如何实现秒级百万TPS?搜索离线大数据平台架构解读》--阅读
离线?在阿里搜索工程体系中我们把搜索引擎.在线算分.SearchPlanner等ms级响应用户请求的服务称之为“在线”服务:与之相对应的,将各种来源数据转换处理后送入搜索引擎等“在线”服务的系统统称为 ...
- version_compare ()
version_compare() ----对比两个「PHP 规范化」的版本数字字符串 version_compare ( string $version1 , string $version2 [, ...
- WinSxS目录下文件的清除
1)McAfee Scanner service 持续高cpu 2)上网查到了,需要看 %deflogdir%目录下的OnDemandScan_Activity.log 3) 打开这个文件,发觉一直在 ...
- Spring Cloud和Spring Boot的版本问题
很多人在使用springboot和springcloud,但是对于这两者之间的版本关系不是很清楚,特别是在面临升级的时候不知道该如何操作.本文简要摘录的官方文档的部分内容作为依据,供广大同行参考. 问 ...
- LeetCode 557:反转字符串中的单词 III Reverse Words in a String III
公众号:爱写bug(ID:icodebugs) 给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序. Given a string, you need to reve ...
- Autoware 培训笔记 No. 4——寻迹
1. 前言 好多初创公司公布出来的视频明显都是寻迹的效果,不是说寻迹不好,相反可以证明,寻迹是自动技术开始的第一步. 自动驾驶寻迹:一种能够自动按照给定的路线(通常是采用不同颜色或者其他信号标记来引导 ...