ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python网络编程之hsahlib 加密 文件效验 服务端的合法性效验 TCP登陆

2022-04-10 03:02:16  阅读:188  来源: 互联网

标签:hashlib python res TCP print 效验 hs encode md5


hashlib模块

hashlib 这个模块是一堆加密算法的集合体,哈希算法的加密方式不止一种
https://www.cmd5.com/ md5解密
应用场景:在需要效验功能时使用
  用户密码的 => 加密,解密
  相关效验的 => 加密,解密

哈希算法也叫摘要算法,相同的数据始终得到相同的输出,不同的数据得到不同的输出。
(1)哈希将不可变的任意长度的数据,变成具有固定长度的唯一值
(2)字典的键和集合的值是通过哈希计算存储的,存储的数据是散列(无序)

 

hashlib

场景: 网站密码加密
hashlib模块的加密原则是单向不可逆的


md5算法 : 可以把字符串变成具有固定长度的32位十六进制字符串

撞库破解

111222  => 00b7691d86d96aebd21dd9e138f90840
222333  => 00b7691d86d96aebd21dd9e138f90842

 

基本语法

import hashlib
import random

# ### 基本语法
# (一)md5对象
# 1.创建md5对象
hs = hashlib.md5()
# 2.把要加密的数据更新到对象中  [update => 把字节流更新到对象之后,进行加密]
hs.update("111222".encode("utf-8"))
# 3.获取十六进制的字符串
res = hs.hexdigest()
print(res   ,   len(res))  # 00b7691d86d96aebd21dd9e138f90840 


# 加盐 (加key , 加一个关键字)
hs = hashlib.md5("XBOYww_".encode())
hs.update("111222".encode())
res = hs.hexdigest()
print(res)  # 623e0e8d4ecabd638c36a5e40189ba8f


# 动态加盐
res = str(random.randrange(100000,1000000))
hs = hashlib.md5(res.encode())
hs.update("111222".encode())
res = hs.hexdigest()
print(res)

# (二)sha系列算法
"""无论是加盐 还是 加密密码,都需要数据类型为二进制字节流"""
# hs = hashlib.sha1()  # 结果是具有固定长度40位的十六进制字符串;
hs = hashlib.sha512("XGIRLww_".encode())  # 结果是具有固定长度128位的十六进制字符串
hs.update("sha系列算法".encode())
res = hs.hexdigest()
"""20c2502d0e00bf8fe35ebfbf097049d1f070e7968f30ef3353ff33d311af50da6b3883bfb9ab411f9dc4cdcd2310b39f5815c6dc1c48cd138d07443a6bcdcd11 128"""
print(res , len(res))  

 
# (三)hmac加密算法
import hmac
import os
key = b"xdogaa_"
msg = b"112233"
# new(盐(字节流),密码(字节流) )
hm = hmac.new(key,msg)
res = hm.hexdigest()
"""
eebe14b1c144092121236cb1e3da396a
"""
print(res , len(res))

# 动态加盐
"""
os.urandom(位数) 返回随机的二进制字节流
res = os.urandom(10)
print(res , len(res))
"""

key = os.urandom(64)
msg = b"112233"
hm = hmac.new(key,msg)
res = hm.hexdigest()
print(res , len(res))
View Code

文件效验

"""
mode = "r"  fp.read(3) 3个字符
mode = "rb" fp.read(3) 3个字节
"""
import hashlib
import os
# (1) 针对于小文件进行校验
def check_md5(filename):
    hs = hashlib.md5()
    with open(filename , mode="rb" ) as fp:
        hs.update(fp.read())
        # return fp.read() 仅仅适用于小文件
    return hs.hexdigest()
    
res1 = check_md5("lianxi1.py")
res2 = check_md5("lianxi2.py")
print(res1 == res2)


# (2) 针对于大文件进行校验
"""update 可以分批次进行加密  等价于一次性加密的结果"""
# update的使用
strvar = "今天是周五,明天自习"
hs = hashlib.md5()
hs.update(strvar.encode())
res1 = hs.hexdigest()
print(res1)

strvar2 = ",周一上午考试,小人射击+计算器"
hs.update(strvar2.encode())
res2 = hs.hexdigest()
print(res2) # 0163aa435c2eea52fac354ba7e6c84da

strvar = "今天是周五,明天自习,周一上午考试,小人射击+计算器"
hs2 = hashlib.md5()
hs2.update(strvar.encode())
print(hs2.hexdigest()) # 0163aa435c2eea52fac354ba7e6c84da

# 方法一
def check_md5(filename):
    hs = hashlib.md5()
    with open(filename,mode="rb") as fp:
        while True:
            # 最多读取5个字节
            content = fp.read(5)
            # 判断读取的字节如果是空,终止循环
            if content:            
                hs.update(content)
            else:
                break
        return hs.hexdigest()

res1 = check_md5("lianxi1.py")
res2 = check_md5("lianxi2.py")
print(res1 , res2)

# 方法二
def check_md5(filename):
    hs = hashlib.md5()
    filesize = os.path.getsize(filename)
    print(filesize)
    with open(filename,mode="rb") as fp:
        # filesize 如果为空,循环终止;
        while filesize:
            content = fp.read(100)
            hs.update(content)
            # 减去实际读取的字节长度
            filesize -= len(content)
        
        return hs.hexdigest()        
        
res1 = check_md5("lianxi1.py")
res2 = check_md5("lianxi2.py")
print(res1 , res2)
View Code

 

肉眼根本看不出下面两个文件哪不一样 

lianxi1.py文件

# ### hashlib 
"""
场景: 网站密码加密
hashlib模块的加密原则是单向不可逆的
md5算法 : 可以把字符串变成具有固定长度的32位十六进制字符串
"""

# 撞库
"""
111222  => 00b7691d86d96aebd21dd9e138f90840
222333  => 00b7691d86d96aebd21dd9e138f90842
"""

import hashlib
import random

# ### 基本语法
# (一)md5对象
# 1.创建md5对象
hs = hashlib.md5()
# 2.把要加密的数据更新到对象中  [update => 把字节流更新到对象之后,进行加密]
hs.update("111222".encode("utf-8"))
# 3.获取十六进制的字符串
res = hs.hexdigest()
print(res   ,   len(res))  # 00b7691d86d96aebd21dd9e138f90840 


# 加盐 (加key , 加一个关键字)
hs = hashlib.md5("XBOYww_".encode())
hs.update("111222".encode())
res = hs.hexdigest()
print(res)  # 623e0e8d4ecabd638c36a5e40189ba8f


# 动态加盐
res = str(random.randrange(100000,1000000))
hs = hashlib.md5(res.encode())
hs.update("111222".encode())
res = hs.hexdigest()
print(res)

# (二)sha系列算法
"""无论是加盐 还是 加密密码,都需要数据类型为二进制字节流"""
# hs = hashlib.sha1()  # 结果是具有固定长度40位的十六进制字符串;
hs = hashlib.sha512("XGIRLww_".encode())  # 结果是具有固定长度128位的十六进制字符串
hs.update("sha系列算法".encode())
res = hs.hexdigest()
"""20c2502d0e00bf8fe35ebfbf097049d1f070e7968f30ef3353ff33d311af50da6b3883bfb9ab411f9dc4cdcd2310b39f5815c6dc1c48cd138d07443a6bcdcd11 128"""
print(res , len(res))  

 
# (三)hmac加密算法
import hmac
import os
key = b"xdogaa_"
msg = b"112233"
# new(盐(字节流),密码(字节流) )
hm = hmac.new(key,msg)
res = hm.hexdigest()
"""
eebe14b1c144092121236cb1e3da396a
"""
print(res , len(res))

# 动态加盐
"""
os.urandom(位数) 返回随机的二进制字节流
res = os.urandom(10)
print(res , len(res))
"""

key = os.urandom(64)
msg = b"112233"
hm = hmac.new(key,msg)
res = hm.hexdigest()
print(res , len(res))
View Code

lianxi2.py文件

# ### hashlib 
"""
场景: 网站密码加密
hashlib模块的加密原则是单向不可逆的
md5算法 : 可以把字符串变成具有固定长度的32位十六进制字符串
"""

# 撞库
"""
111222  => 00b7691d86d96aebd21dd9e138f90840
222333  => 00b7691d86d96aebd21dd9e138f90842
"""

import hashlib
import random

# ### 基本语法
# (一)md5对象
# 1.创建md5对象
hs = hashlib.md5()
# 2.把要加密的数据更新到对象中  [update => 把字节流更新到对象之后,进行加密]
hs.update("111222".encode("utf-8"))
# 3.获取十六进制的字符串
res = hs.hexdigest()
print(res   ,   len(res))  # 00b7691d86d96aebd21dd9e138f90840 


# 加盐 (加key , 加一个关键字)
hs = hashlib.md5("XBOYww_".encode())
hs.update("111222".encode())
res = hs.hexdigest()
print(res)  # 623e0e8d4ecabd638c36a5e40189ba8f


# 动态加盐
res = str(random.randrange(100000,1000000))
hs = hashlib.md5(res.encode())
hs.update("111222".encode())
res = hs.hexdigest()
print(res)

# (二)sha系列算法
"""无论是加盐 还是 加密密码,都需要数据类型为二进制字节流"""
# hs = hashlib.sha1()  # 结果是具有固定长度40位的十六进制字符串;
hs = hashlib.sha512("XGIRLww_".encode())  # 结果是具有固定长度128位的十六进制字符串
hs.update("sha系列算法".encode())
res = hs.hexdigest()
"""20c2502d0e00bf8fe35ebfbf097049d1f070e7968f30ef3353ff33d311af50da6b3883bfb9ab411f9dc4cdcd2310b39f5815c6dc1c48cd138d07443a6bcdcd11 128"""
print(res , len(res))  

 
# (三)hmac加密算法
import hmac
import os
key = b"xdogaa_"
msg = b"112233"
# new(盐(字节流),密码(字节流) )
hm = hmac.new(key,msg)
res = hm.hexdigest()
"""
eebe14b1c144092121236cb1e3da396a
"""
print(res , len(res))

# 动态加盐
"""
os.urandom(位数) 返回随机的二进制字节流
res = os.urandom(10)
print(res , len(res))
"""

key = os.urandom(64)
msg = b"112233"
hm = hmac.new(key,msg)
res = hm.hexdigest()
print(res , len(res))
View Code

 

 

服务端的合法性效验

客户端

""" 机器和机器之间的数据直接对接 """
import socket
import hmac

sk = socket.socket()
sk.connect( ("127.0.0.1" , 9000) )

def auth(secret_key):
    # 接受服务端发送过来的随机二进制字节流
    msg = sk.recv(32)
    
    # hmac.new(   key(字节流) ,  要加密的内容(字节流)  )
    hm = hmac.new( secret_key.encode() , msg  )
    
    # 返回的是具有固定32位长度的十六进制字符串
    cli_res = hm.hexdigest()
    
    # 把最后计算的结果发送给服务端进行校验
    sk.send(  cli_res.encode() )
    
    # 接受服务端给予的校验结果
    res = sk.recv(1024).decode()
    
    return res
    


# 处理收发数据的逻辑
secret_key = "不开,老妈没回来"
secret_key = "小兔儿乖乖,把门开开"
# 调用授权函数
res = auth(secret_key)

if res == "True":
    print("服务器校验通过")
else:
    print("服务器校验失败")

sk.close()
View Code

服务端

""" 机器和机器之间的数据直接对接 """
import socketserver
import hmac
import os

class MyServer(socketserver.BaseRequestHandler):

    secret_key = "小兔儿乖乖,把门开开"

    def auth(self):
        conn = self.request
        # 创建一个随机的32位字节流
        msg = os.urandom(32)
        
        # 把字节流发送给客户端
        conn.send(msg)
        
        # 服务端进行数据校验
        hm = hmac.new(  self.secret_key.encode() , msg  )
        ser_res = hm.hexdigest()
        
        # 服务端接受客户端发送过来的数据结果
        cli_res = conn.recv(1024).decode()
        
        # 进行比对,如果ok 返回True , 反之亦然
        return  True if ser_res == cli_res else False            

    def handle(self):
        if self.auth():
            self.request.send("True".encode())
        else:
            self.request.send("False".encode())

server = socketserver.ThreadingTCPServer( ("127.0.0.1" , 9000)  , MyServer  )
# 开启,让一个端口绑定多个程序;  模块.类.属性 = True
socketserver.TCPServer.allow_reuse_address = True
server.serve_forever()
View Code

 

 

TCP登陆

客户端

import socket 
import json
"""
pickle => 字节流( 存储数据 )
json   => 字符串( 数据交互 )
"""

sk = socket.socket()
sk.connect( ("127.0.0.1" , 9001) )

# 处理收发数据的逻辑
usr = input("请输入您的用户名:")
pwd = input("请输入您的密码:")
dic = {"username" : usr , "password":pwd , "operate" : "login"}

# 通过json变成字符串
res = json.dumps(dic)

# 转化成字节流发送给服务端
sk.send(res.encode())

# 接受服务端响应的数据
res_str = sk.recv(1024).decode()

# 字符串转化成字典
dic = json.loads(res_str)
print(dic , type(dic))
print(dic["msg"])


sk.close()
View Code

服务端

from collections import Iterator,Iterable
import socketserver
import hashlib
import json

class MyServer(socketserver.BaseRequestHandler):

    # 默认没有登录
    sign = False
    
    def get_md5_code(self,usr,pwd):
        hs = hashlib.md5(usr.encode())
        hs.update(pwd.encode())
        return hs.hexdigest()

    def auth(self):
        
        conn = self.request
        # 接受客户端发送过来的数据,通过decode反解成字符串
        res = conn.recv(1024).decode()
        # 通过json把字符串 转换成 字典
        dic = json.loads(res)
        # {'username': 'caijingguan', 'password': '8888', 'operate': 'login'} 
        print(dic , type(dic)) 
        with open("userinfo.data",mode="r",encoding="utf-8") as fp: # fp文件对象是迭代器,一行一行返回数据
            for i in fp:
                # 文件中解析出用户和密码
                usr,pwd = i.strip().split(":")
                if usr == dic["username"] and pwd == self.get_md5_code( dic["username"] , dic["password"] ) : 
                    # 自定义返回的字典数据
                    dic_msg = {"code":1,"msg":"登录成功"}
                    # 把字典 => 字符串
                    json_str = json.dumps(dic_msg)
                    # 把字符串 => 字节流 发送给客户端
                    conn.send( json_str.encode() )
                    # 把sign标记从False => True 代表登录成功
                    self.sign = True
                    break
                    
            # 没有找到对应合法的用户名和密码,登录失败
            if self.sign == False:
                dic_msg = {"code":0,"msg":"登录失败"}
                res = json.dumps(dic_msg).encode()
                conn.send(res)        
        
    def handle(self):
        self.auth()

server = socketserver.ThreadingTCPServer( ("127.0.0.1" , 9001) , MyServer )
# 开启,让一个端口绑定多个程序;  模块.类.属性 = True
socketserver.TCPServer.allow_reuse_address = True
server.serve_forever()
View Code

 

创建一个userinfo.data文件存储用户数据 密码用hshlib加密

userinfo.data

        wangwen:bbccc59bedc09e551a394699b44ed9f9
lisi:c79439cf9abcbd6c6d46e45766a9e64a
View Code

 

标签:hashlib,python,res,TCP,print,效验,hs,encode,md5
来源: https://www.cnblogs.com/shuaiyao666/p/16124591.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有