Python 之网络编程之socket(3)hashlib模块
hashlib模块
#hashlib 这个模块是一堆加密算法的集合体,哈希算法的加密方式不止一种
httpswww.cmd5.com md5解密
# 应用场景在需要效验功能时使用
用户密码的 = 加密,解密
相关效验的 = 加密,解密
#哈希算法也叫摘要算法,相同的数据始终得到相同的输出,不同的数据得到不同的输出。
#(1)哈希将不可变的任意长度的数据,变成具有固定长度的唯一值
(2) 字典的键值对映射关系是通过哈希计算的,哈希存储的数据是散列(无序)
1. hashlib基本用法
#例:
import hashlib
##基本用法使用md5加密
# (1)创建一个md5算法的对象
hs = hashlib.md5() # (2)把想要加密的字符串通过update更新到hs这个对象
# 参数是二进制字节流
hs.update("hsz".encode("utf-8")) # (3)返回32位16进制的字符串
res = hs.hexdigest()
print(res)
print(len(res),"位") # (4)加盐 (加key只有你自己知道的明文) 目的: 增加密码的复杂度
hs = hashlib.md5("hsz".encode("utf-8"))
hs.update("".encode("utf-8"))
res = hs.hexdigest()
print(res) #(5)动态加盐
import random
res = str(random.randrange(10000,100000))
hs = hashlib.md5(res.encode())
hs.update("aabbccdd".encode())
res = hs.hexdigest()
print(res)
得到的结果为:(因为最后一个是动态加盐,加入的是随机值,所有最后一个值一直在变化)
071a5dcfd09db850f1ff95131acc5f2c
32 位
72646ae443c21a820b2013262ea43f86
27b72799df64dc1ceca1544ebdd82876
# mod5 加密效率快 ,通用的加密方法,安全性稍差 位数是32位
# sha 加密效率慢 ,算法相对来精密,安全性稍高
##基本用法使用sha系列密方法
#例:
import hashlib hs = hashlib.sha1()
hs.update("hahaha_123".encode())
res = hs.hexdigest()
# 返回的加密的字符串长度是40位
print(res)
print(len(res),"位") # 加密
hs = hashlib.sha1("qwe".encode())
hs.update("xx_qq123".encode())
res = hs.hexdigest()
print(res) # sha512
hs = hashlib.sha512()
hs.update("".encode())
res = hs.hexdigest()
#返回的字符串长度是128位
print(res)
print(len(res),"位")
输出结果为:
f1817bcbd94c1b26f5e25ed375b92de337cfe38d
40 位
a2affd3f2502b5de251e6e7704a9d5d641e5338a
ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413
128 位
##基本用法使用hmac 加密
#hmac 加密的算法更加不容易破解
#例:
import hashlib
import hmac
import os
key = b""
msg = b"" # hmac里面的new方法相当于hashlib 创建对象和update 粘合在一起操作
hm = hmac.new(key,msg)
res = hm.hexdigest()
print(res)
print(len(res),"位") # 随机返回长度为32位的二进制字节流(加盐)
key = os.urandom(32)
print(key) hs = hmac.new(key,msg)
res = hs.hexdigest()
print(res)
print(len(res),"位")
由于后面两个加密时加盐,所有后面两个输出会一直在变化,这样安全性更强:
#第一次运行:
eade56028e252b77f7a0b8792e58b9cc
32 位
b'\xb7wQ\xe4\r5\x15\xca\xc3\x7fUY\xc3\xcb\x84<\x10\x7f\xb1\x8b\xac_\x04\xf2\x8b\x948C\x1e\xa6\x1a\x10'
fa9e0bceb2effd7adbcdb76b414ccf95
32 位
#第二次运行:
eade56028e252b77f7a0b8792e58b9cc
32 位
b'\xf6\x08\xf5\x8d8+4\xec\xad[\xc0#T^\xed\xb2{V\xa4\xe9\xb5\xb7\xe5>\xecn\xf6\xd4\xe3\xe3\xb6\x87'
fe78046eae3682d73ac9cfd838c4800c
32 位
2.文件效验
首先需要创建两个文件:ceshi1.txt ceshi2.txt,然后都输入aaaaa,两个文件内容相同:
#例:
import hashlib
# (1) 针对小文件的内容效验
def check_md5(file):
with open(file, mode="rb") as fp:
hs = hashlib.md5()
hs.update(fp.read()) return hs.hexdigest() print(check_md5("ceshi1.txt"))
print(check_md5("ceshi2.txt"))
输出结果为:
594f803b380a41396ed63dca39503542
594f803b380a41396ed63dca39503542
如果文件过大,是一次性读取不了的,所有(1)的方法只适合小文件的内容效验
#例:
import hashlib
# (2) 针对于大文件的内容效验
hs = hashlib.md5()
hs.update("昨天晚上\n下雨了".encode())
res = hs.hexdigest()
print(res) # 894c4dd4b1f57472322db524e7b6a47f # 可以连续update 到hs对象进行字节流的拼接
hs = hashlib.md5()
hs.update("昨天晚上\n".encode())
hs.update("下雨了".encode())
res = hs.hexdigest()
print(res)
输出结果为:
894c4dd4b1f57472322db524e7b6a47f
894c4dd4b1f57472322db524e7b6a47f
#例:
import hashlib # 方法一
def check_md5_01(file):
hs = hashlib.md5()
with open(file,mode="rb") as fp:
while True:
content = fp.read(1)
if content:
hs.update(content)
else:
break
return hs.hexdigest() print(check_md5_01("ceshi1.txt"))
print(check_md5_01("ceshi2.txt")) print("========================")
# 方法二
import os
def check_md5_02(file):
hs = hashlib.md5()
file_size = os.path.getsize(file)
with open(file,mode="rb") as fp:
while file_size:
# read(1) 最多最多读一个,如果文件空了就不读了
content = fp.read(1)
hs.update(content)
file_size -= len(content)
return hs.hexdigest() print(check_md5_02("ceshi1.txt"))
print(check_md5_02("ceshi2.txt"))
输出结果为:
594f803b380a41396ed63dca39503542
594f803b380a41396ed63dca39503542
========================
594f803b380a41396ed63dca39503542
594f803b380a41396ed63dca39503542
3.hashlib之hmac加密socket应用一(效验秘钥)
模拟客户端连接服务端需要秘钥的情况的过程
服务端代码:
import socket
import hmac
import os
def auth(conn, secret_key):
# 随机获取二进制的字节流
msg = os.urandom(32)
#print(msg) conn.send(msg)
hm = hmac.new(secret_key, msg)
res_serve = hm.hexdigest()
# 接收客户端发给我的字符串
res_client = conn.recv(1024).decode("utf-8")
if res_serve == res_client:
print("合法的链接")
return True
else:
print("不合法的链接")
return False sk = socket.socket()
sk.bind(("127.0.0.1", 9009))
sk.listen() conn,addr = sk.accept()
secret_key = b"hszhahaha" if auth(conn,secret_key):
# 如果返回真,可以接收客户发过来的各种请求
print(conn.recv(1024).decode("utf-8")) # 收发数据逻辑.
# ... # 四次挥手
conn.close()
# 退还端口
sk.close()
客户端代码:
import socket
import hmac def auth(sk, key):
# 接收服务器发过来的随机二进制字节流
msg = sk.recv(32)
# print(msg)
hm = hmac.new(key, msg)
res = hm.hexdigest() # 把加密后的字符串发送给服务器
sk.send(res.encode()) sk = socket.socket() key = b"hszhahaha"
sk.connect(("127.0.0.1", 9009))
auth(sk,key)
sk.send(b"download")
sk.close()
3.hashlib之md5加密socket应用二(验证登录)
首先需要创建一个用户信息包括用户名和加密后的密码:
解密的方式是已用户名为盐值,用密码+用户名进行md5加密
在userinfo.txt内存入这三个信息密码加密后存入文本:
zhangsan 111
li 222
wangwu 333
解密的内容如图方式:

服务端代码为:
import socket
import json
# zhangsan 111
# li 222
# wangwu 333 sk = socket.socket()
sk.connect(("127.0.0.1", 9005)) # 收发数据的逻辑
usr = input("请输入用户名:")
pwd = input("请输入您的密码:")
dic = {"username":usr,"password":pwd,"operate":"login"} # 把字典系列化成字符串
json_dic = json.dumps(dic) #把字符串变成字节流
bytes_msg = json_dic.encode("utf-8")
sk.send(bytes_msg) # 接收服务器的返回值
res_msg = sk.recv(1024).decode() # 反序列化成字典
dic_code = json.loads(res_msg)
if dic_code['code']:
print("恭喜你,登录成功")
else:
print("抱歉,登录失败")
客户端代码为:
import socket
import json
import hashlib def get_md5_code(usr, pwd):
hs = hashlib.md5(usr.encode())
hs.update(pwd.encode())
return hs.hexdigest() sk = socket.socket()
sk.bind(("127.0.0.1", 9005))
sk.listen() conn,addr = sk.accept()
# 把接收的字节流变成字符串
msg = conn.recv(1024).decode() # 反序列化字典
dic = json.loads(msg) # 默认编辑用户不存在
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']):
res = {"code":1}
res_msg = json.dumps(res).encode()
conn.send(res_msg)
# 该用户找到了,存在
sign = True
break
if sign == False:
res = {"code":0}
res_msg = json.dumps(res).encode()
conn.send(res_msg) conn.close()
sk.close()
#运行结果是,在客户端让其输入用户密码:
#如果用户或密码错误会返回登录失败:

#如果用正确的用户密码输入返回成功:

Python 之网络编程之socket(3)hashlib模块的更多相关文章
- Python 之网络编程之socket(2)黏包现象和socketserver并发
一:黏包 ###tcp协议在发送数据时,会出现黏包现象. (1)数据粘包是因为在客户端/服务器端都会有一个数据缓冲区, 缓冲区用来临时保存数据,为了保证能够完整的接收到数据,因此缓冲区 ...
- Python 之网络编程之socket(1)TCP 方式与UDP方式
一:socket介绍 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. 建立网络通信连接至少要一对端口号(socket).socket本质是编程接口(API) ...
- 网络编程之socket
网络编程之socket socket:在网络编程中的一个基本组件,也称套接字. 一个套接字就是socket模块中的socket类的一个实例. 套接字包括两个: 服务器套接字和客户机套接字 套接字的实例 ...
- 网络编程之Socket & ServerSocket
网络编程之Socket & ServerSocket Socket:网络套接字,网络插座,建立网络通信连接至少要一对端口号(socket).socket本质是编程接口(API),对TCP/IP ...
- GO语言的进阶之路-网络编程之socket
GO语言的进阶之路-网络编程之socket 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是socket; 在说socket之前,我们要对两个概念要有所了解,就是IP和端口 ...
- [深入浅出Cocoa]iOS网络编程之Socket
http://blog.csdn.net/kesalin/article/details/8798039 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] [深入浅出Co ...
- 网络编程之Socket代码实例
网络编程之Socket代码实例 一.基本Socket例子 Server端: # Echo server program import socket HOST = '' # Symbolic name ...
- [网络编程之Socket套接字介绍,套接字工作流程,基于TCP协议的套接字程序]
[网络编程之Socket套接字介绍,套接字工作流程,基于TCP协议的套接字程序] 为何学习socket套接字一定要先学习互联网协议: 1.首先:要想开发一款自己的C/S架构软件,就必须掌握socket ...
- Python自动化运维之15、网络编程之socket、socketserver、select、twisted
一.TCP/IP相关知识 TCP/UDP提供进程地址,两个协议互不干扰的独自的协议 TCP :Transmission Control Protocol 传输控制协议,面向连接的协议,通信 ...
随机推荐
- STM32CUBEMX使用操作记录
1.New Project 2.选择芯片型号 3.配置相关外设 4.例如选择了GPIO_Output 5.配置时钟树 灰色框点不了,这和你上一步相关外设配置有关,鼠标靠近灰色框,系统会给出提示 6.工 ...
- springboot 框架 - helloword
功能:浏览器发送hello请求,服务器接收请求并处理,返回hello word字符串 一.创建一个maven项目 二.在pom.xml文件中添加依赖导入springboot框架运行需要的依赖 < ...
- 【MySQL】单表查询
" 目录 where 约束 group by 分组查询 聚合函数 having 过滤 order by 查询排序 limit 限制查询的记录数 # 语法 select 字段1, 字段2 .. ...
- Javascript中forEach的异步问题
某天尝试了下在 forEach函数中调用 await Promise() 方法,如下: var arr = [1,2,3] arr.forEach(async (v,i,a)=>{ await ...
- ubuntu 18.04中nginx不能访问软链接目录中的内容
解决办法:以root权限运行nginx,即修改/etc/nginx/nginx.conf中的user www-data为root
- SpringCloud全家桶学习之客户端负载均衡及自定义负载均衡算法----Ribbon(三)
一.Ribbon是什么? Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 负载均衡的工具(这里区别于nginx的负载均衡).简单来说,Ribbon是Netf ...
- 【Go语言系列】第三方框架和库——GIN:快速入门
要求要安装Gin软件包,需要:1.安装Go(需要1.11+版本)2.设置Go工作区 安装1.下载并安装 gin: $ go get -u github.com/gin-gonic/gin 2.将 gi ...
- CN109241772A发票区块链记录方法、装置、区块链网关服务器和介质(腾讯)
学习笔记-2 CN109241772A发票区块链记录方法.装置.区块链网关服务器和介质(腾讯) 解决什么问题? 让发票信息记录到区块链的情况下减少发票信息泄露 链上有什么数据? 发行发票事件信息(发票 ...
- 【原】Django总结
centos7下部署django详细步骤:https://www.cnblogs.com/djangocn/p/9538551.html 快速入门:https://www.cnblogs.com/ze ...
- 洗牌利器——random.shuffle()函数
random.shuffle()是一个非常实用但是又非常容易被忽略的函数,shuffle在英语里是"洗牌"的意思,该函数非常形象地模拟了洗牌的过程,即: random.shuffl ...