博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Day28 hashlib模块、合法性校验、tcp登录
阅读量:4625 次
发布时间:2019-06-09

本文共 7355 字,大约阅读时间需要 24 分钟。

1.hashlib模块

mad()/sha1()/sha512.../hmac()

#hashlib 这个模块是一堆加密算法的集合体,哈希算法的加密方式不止一种

https://www.cmd5.com/ md5解密
# 应用场景:在需要效验功能时使用
用户密码的 => 加密,解密
相关效验的 => 加密,解密

#哈希算法也叫摘要算法,相同的数据始终得到相同的输出,不同的数据得到不同的输出。

#(1)哈希将不可变的任意长度的数据,变成具有固定长度的唯一值
(2)字典的键值对映射关系是通过哈希计算的,哈希存储的数据是散列(无序)

##mad加密(相比而言hmac加密的算法不会被破解)

加密效率快 通过的加密精密 方法安全性稍差 位数是32位

# 基本用法# (1)创建一个md5算法的对象# (2)把想要加密的字符串通过update方法更新到hs这个对象当中去# 参数是二进制字节流# (3)返回的是32位16进制的字符串# 加盐(加key 只有你自己知道的明文) 目的:增加密码的复杂度 # 加盐是在用md5后者是sha1()或者sha512()时候假如参数key # 在hashlib.md5(key)# 动态加盐
hs = hashlib.md5()hs.update("wangwenshuaige".encode("utf-8"))res = hs.hexdigest()print(res,len(res))# a9d3c3ad36ff18b5bc7be96295df079b 32# 加盐(加key 只有你自己知道的明文) 目的:增加密码的复杂度hs = hashlib.md5("Xboyww_".encode("utf-8"))hs.update("123".encode("utf-8"))res = hs.hexdigest()print(res)# 1ea36fffc2174b753b4c47d3deeaca60# 动态加盐import randomres = str(random.randrange(10000,1000000))hs = hashlib.md5(res.encode())hs.update("aabbccdd".encode())res = hs.hexdigest()print(res)# 485e1769395b018243d7ee16f2540219

## sha

加密效率慢,算法相对来说 安全性稍高

 # 1.创建一个对象

# 2. 对象.update(key) 写入的数据都是字节流的

# 比如:hs = hashlib.sha1()

  hs.update("xboyww_123".encode("utf-8"))

 

hs = hashlib.sha1()hs.update("xboyww_123".encode("utf-8"))res = hs.hexdigest()# 返回的加密字符串长度是40位print(res,len(res))# 4f584b41e8cca8c45f4875ddbfa8113dffa36e31 40# 加盐hs = hashlib.sha1("PPUU".encode("utf-8"))hs.update("xboyww_123".encode())res = hs.hexdigest()print(res)# 744316f7f3c985b49c3b0412f5e8444ea861c4d1# sha512hs = hashlib.sha512()hs.update("12345".encode())res = hs.hexdigest()# 返回的字符串长度是128位print(res,len(res))# 3627909a29c31381a071ec27f7c9ca97726182aed29a7ddd2e54353322cfb30abb9e3a6df2ac2c20fe23436311d678564d0c8d305930575f60e2d3d048184d79 128

 

# hmac

hmac里面的new方法相当于hashlib差古剑对象和update联合在一起的操作.

 

import hmacimport oskey = b"124"msg = b"456"hm = hmac.new(key,msg)res = hm.hexdigest()print(res,len(res))# abd3b78f7a6c0a170381a7094c09c777 32# 随机返回长度为32位的二进制字节流key = os.urandom(32)print(key)# b'\xfe\xf2\xe3\xf7\xb7\xcc@\x8dLx\xf42\x85\xbd\x99Z\xfa\xe0\x9f\x0c\xe0\xa2\x9bT\xb2h\xd8\x1b\xeb\x98J\x15'hm = hmac.new(key,msg)res = hm.hexdigest()print(res,len(res))# 5c7e1d2e4d48bd14149a8afe5f4904fc 32

 

2.合法性校验

1.小文件的校验

(1)针对小文件的内容校验import hashlibdef 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"))# 62c629da1d7f164bb85e2d741b77610e# b949a12fb038471495f0cdb8db640562 # 可以连续的对内容就行校验
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
 

 

2.大文件的校验

# 方法一def check_md5(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("<=======>")print(check_md5("ceshi1.txt"))print(check_md5("ceshi2.txt"))# 62c629da1d7f164bb85e2d741b77610e# b949a12fb038471495f0cdb8db640562
# 方法二 import osdef check_md5(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("ceshi1.txt"))print(check_md5("ceshi2.txt"))# 62c629da1d7f164bb85e2d741b77610e# b949a12fb038471495f0cdb8db640562 # 利用创建出来的对象可以持续的update()即是你需要校验的内容,如果需要加(加盐)key(明文)就在创造对象的时候加入。
hs = hashlib.md5("Xboyww_".encode("utf-8"))
小结:方法1是利用一个死循环,每次在里面就行读取一个字节,如果读到有数据的话就就行update()把要校验的内容加进去。直到fp.read(1)读不到数据的时候就行退出,最后返回一个hs.hexdigest() 方法二是利用判断文件大小作为循环的条件,一样的就行每次读取一个字节,利用update()方法就行更新hs对象,直到文件对象file_size的长度为0的时候,说明要校验的内容已经全部写入hs对象中去了。 最后直接返回hs.hexdigest()

3.tcp登录

1.客户端访问服务器时,在服务器端加入一段数据的验证,如果验证通过就可以正常的访问服务器,如果验证不通过不可以访问。

1.除了客户端和服务器端之间约定的一些代码之外,服务器器端还(在验证数据的时候加盐了,加入的数据是随机产生的32位的字节流数据)

例:

客服端发送给服务器的验证数据:

b"wangwendashuaige"

服务器需要的验证数据:(双方约定好,如果你来访问服务器就必须是这个词,再者考虑到安全的因素,服务器随机增加了一个32位字节的数据并发送给客户端,要求客户端把这个数据和key(盐一起打包发过去))

 # 客户端代码

import socketimport hmacdef 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"wangwendashuaige"sk.connect( ("127.0.0.1",9000) )auth(sk,key)sk.send(b"download")sk.close()

 

# 服务器代码

# server 服务端 添加访问的权限验证import socketimport hmacimport osdef 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 Falsesk = socket.socket()sk.bind( ("127.0.0.1",9000) )sk.listen()conn,addr = sk.accept()secret_key = b"wangwendashuaige"if auth(conn,secret_key):    # 如果返回真,可以接受客户发来的各种请求    print(conn.recv(1024).decode("utf-8"))# 收发数据逻辑.# ...# 四次挥手conn.close()# 退还端口sk.close() 运行代码:True
Flase:服务端的代码:不合法的链接
小结:1.本例子当中客户端第一次发送的是通过hmac("双方规定的键值","接收到服务器发送的数据当做即将发送的数据")
     2.然后客户端将要发送到服务器就行验证的数据就行hmac发送过去
     3.服务器端就行判断,如果是正确的.../如果是错误的....
   4,本例子客户端只是利用send发送了2次数据,没有接受数据,故客户端没有代码。

 

2.带有输入用户名和密码的,访问服务器(已经存好了可以访问的内容),程序过程是:

1.通过将输入的用户名还有密码通过json转换为字符串再

2.通过encode变成二进制字节流,然后使用hashlib就行加密发送

3.到了服务器端,就行decode()得到当初定义的字典,这个时候需要访问服务器端的数据库的数据就行文件的比对:

       但是本例子中服务器去拿数据的时候,不是拿的数据库的数据而是自己创建的数据,直接通过打开文件数据就行获取就行,但是注意数据的格式,以及收到的数据不要搞混淆了。

      服务器中的数据类型是通过hashlib加密过的(本例中的是:# zhangsan:e7a6d0f97db7ea1c4a0c1c137cbf771c;也就是密码是经过hashlib的)。接收到客户端的数据是字节流,

  如果是正确的:返回一个字典{“code”:1} 并把标记状态的sign = True(最初定义的是False,定义这个状态方便我们就行在客户端就行接受一个数据,从而反应出访问的结果)

4.通过一变量的增加(sign=0,成功之后是sign=1,不做处理如果是sign=0后面继续写逻辑),并发送回客户端,让客户端知道反应结果。

服务器数据库中存放的数据是:

服务器代##服务器登录import socket

import jsonimport hashlibdef 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",9001))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 breakif sign == False: res = {
"code":0} res_msg = json.dumps(res).encode() conn.send(res_msg)conn.close()sk.close()

 

客户端代码:

### 客户端import socketimport json## 张三 111# 李四 222# 王五 333# 赵六 444sk = socket.socket()sk.connect(("127.0.0.1", 9001))# 收发数据逻辑usr = input("请输入用户名:")pwd = input("请输入您的密码:")dic = {
"username": usr, "password": pwd, "operation":"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("抱歉,登录失败!")sk.close

 

 

转载于:https://www.cnblogs.com/longerandergou/p/10969125.html

你可能感兴趣的文章
WPF listbox数据绑定
查看>>
实现鼠标移到某个对象,在旁边显示层。
查看>>
函数 加分
查看>>
Jenkins+GitLab
查看>>
C++学习笔记2——引用
查看>>
url
查看>>
[小北De编程手记] : Lesson 01 玩转 xUnit.Net 之 概述
查看>>
LeetCode "Median of Two Sorted Arrays"
查看>>
PAT 1004. Counting Leaves (30)
查看>>
首先你得承认世界上有全面超过你的人
查看>>
20165204 Java第二周学习
查看>>
php数组转xml
查看>>
Binary Tree Serialisation Lintcode
查看>>
C# LINQ学习笔记
查看>>
easyui select 下拉框的取值和赋值
查看>>
java.lang.IllegalArgumentException: Request header is too large
查看>>
如何解决安卓SDK无法下载Package的问题
查看>>
我的知识组织管理
查看>>
gradle spring boot构建项目
查看>>
MTK 修改默认屏幕亮度
查看>>