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()

#运行结果是,在客户端让其输入用户密码:

#如果用户或密码错误会返回登录失败:

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

最新文章

  1. 如何在VS 2010中使用 VS2013的解决方案(转)
  2. php比较时间戳与时间差计算函数( 实用)
  3. I.MX6 Android 5.1 快速合成系统
  4. Java 中的抽象类及接口
  5. 小白日记13:kali渗透测试之服务扫描(三)-SMTB扫描、防火墙识别、负载均衡识别、WAF识别
  6. 在SQL 2012中使用和Oracle 一样的序列
  7. 在Outlook中设置QQ邮箱
  8. 【虚拟化实战】容灾设计之三Stretched Cluster
  9. 表复制语句select into from 与 insert into select 区别鉴赏
  10. docker--数据卷与数据卷容器
  11. ArcGIS 网络分析[8.3] 设置IDENetworkDataset的属性及INetworkDataset的对比/创建网络数据集
  12. Loadrunner学习资料
  13. MVC之 自定义过滤器(ActionFilterAttribute)
  14. 2018-01-04 浅尝The Little Prover一书, 重逢Chez Scheme
  15. was监控脚本编写时的注意点
  16. SQL EXCEPT INTERSECT
  17. elasticsearch ik安装
  18. mysql的in查询分析
  19. code1044 导弹拦截
  20. 《the art of software testing》第四章 测试用例的设计

热门文章

  1. shell脚本编程学习笔记(三)编写邮件报警脚本
  2. Jmeter 断言使用
  3. ztree-可拖拽可编辑的树
  4. 【转】Docker网络模式--默认模式bridge模式
  5. 【C语言】创建一个函数,判断某一正整数是否为水仙花数,并调用这个函数找出1000以内所有水仙花数
  6. gitlab的搭建与汉化
  7. 数据库单,多,全库、冷热备份思路及备份与还原(mysqldump)
  8. linux +jenkins +python 集成测试
  9. 2.3.FastDFS-单机拆分版-与Nginx整合配置
  10. IDEA中使用Springboot+SSM的踩坑记(一)