3.多线程TCP协议与加密方式

多线程TCP协议与加密方式

1.多线程TCP协议

客户端
# 客户端
import socket

sk = socket.socket() #创建对象
sk.connect(("127.0.0.1",8001)) #建立连接

while True:
    sk.send(b"hello") #发送数据
    res = sk.recv(1024) #接收数据
    print(res.decode())

sk.close() #断开连接
服务端
# 服务端
"""
支持TCP协议下的多线程迸发,一个服务器可以同时连接多个客户端
"""
import socketserver

class MyServer(socketserver.BaseRequestHandler):#自定义类,必须继承父类
    def handle(self):
        conn = self.request #收发数据对象
        while True:
            res = conn.recv(1024) #接收数据
            print(res.decode())
            conn.send(b"haohao") #发送数据
#多线程TCP服务 ThreadingTCPServer((IP,端口号),自定义类)
server = socketserver.ThreadingTCPServer(("127.0.0.1",8001),MyServer) 
server.serve_forever() #永不停机

2.hashlib 加密

"""
应用:
    1.密码加密
    2.文件校验
md5算法:
    可以把字符串变成具有固定32位长度的十六进制字符串
    加密之后,不能反解回原来数据
"""
密码加密
import hashlib
import random

# 一.md5算法
md5算法 : 可以把字符串变成具有固定长度的32位十六进制字符串
加密之后,不能反解

# 基本写法:
hs = hashlib.md5() #1.创建md5对象
# 2.把要加密的数据放到新的对象里,update(参数为二进制字节流)
hs.update("123".encode("utf-8"))
res = hs.hexdigest() #3.获取十六进制32位长度的字符串
print(res,type(res),len(res)) #202cb962ac59075b964b07152d234b70 <class 'str'> 32

# 加盐(加key) 加强保密性
hs = hashlib.md5("jyh".encode()) #加盐,二进制字节流
hs.update("123".encode())
res = hs.hexdigest()
print(res) #5a5f13216c44d4ea9f5baa9a682ed4b9

# 动态加盐
res = random.randrange(30000)
hs = hashlib.md5(str(res).encode())
hs.update("123".encode())
res = hs.hexdigest()
print(res)

# 二.sha系列算法(也是可以加盐的)
hs = hashlib.sha256() #64位长度
hs = hashlib.sha512() #128位长度
hs.update("123".encode())
res = hs.hexdigest()
print(res,len(res))

# 三.hmac加密算法

import hmac
import os
"""
语法:
    new( 盐 , 需要加密的数据 ) 
    参数: 二进制字节流
"""
# 基本写法:
key = b"abc"
msg = b"123"
hm = hmac.new(key,msg)
res = hm.hexdigest() #获取十六进制32位长度的字符串
print(res,len(res)) #725658455c63977e1b73a199970a9972 32

# 动态加盐效果:
# 随机二进制字节流
"""
os.urandom(位数):
    返回随机的二进制字节流,长度有位数决定
"""
key = os.urandom(32)
msg = b"123"
hm = hmac.new(key,msg)
res = hm.hexdigest()
print(res,len(res)) #9ce4239361ccf8a1e09ed0d35bd7a7ff 32
文件校验
# 文件校验
import hashlib

# 1.针对小文件内容进行校验 
"""
可以一次性读取文件所有内容
"""
def check(filename):
    hs = hashlib.md5() #创建md5对象
    with open(filename,mode="rb") as fp:
        res = fp.read() #读取文件
        hs.update(res)
        return hs.hexdigest() #返回数据

res1 = check("1.hashlib加密模块使用.py")
res2 = check("1.hashlib使用.py")
print(res1,res2) #如果res1和res2一样,两个文件内容就是一样的

# 2.针对大文件的内容进行校验
"""
不能一次性读取文件所有内容,需要分配加密
结论:
    update方法,可以把一个字符串分解成多份,分开进行加密
    得出的结果和整体字符串进行加密的值是一致的
"""
# 整体加密
hs = hashlib.md5() #创建md5对象
strvar = "黄河之水天上来,奔流到海不复回"
hs.update(strvar.encode())
res = hs.hexdigest()
print(res) #dea65c92721219ada5c872f4676e2951

# 分开加密
hs = hashlib.md5() #重新创建md5对象
strvar1 = "黄河之水天上来"
hs.update(strvar1.encode())
strvar2 = ",奔流到海不复回"
hs.update(strvar2.encode())
res = hs.hexdigest()
print(res) #dea65c92721219ada5c872f4676e2951

# 大文件校验方法一:
def check(filename):
    hs = hashlib.md5()
    with open(filename,mode="rb") as fp:
        while True:
            content = fp.read(10) #一次最多读取10个字节
            if content:
                hs.update(content)
            else:
                res = hs.hexdigest()
                return res
            
res1 = check("1.hashlib加密模块使用.py")
res2 = check("1.hashlib使用.py")
print(res1,res2) 

# 大文件校验方法二
import os
def check(filename):
    hs = hashlib.md5()
    filesize = os.path.getsize(filename) #获取文件大小
    with open(filename,mode="rb") as fp:
        while filesize: 
            content = fp.read(20) #根据文件大小读取数据,
            hs.update(content)
            filesize -= len(content) #一次最多减去20字节,直到filesize=0时,循环终止
        return hs.hexdigest()

res1 = check("1.hashlib加密模块使用.py")
res2 = check("1.hashlib使用.py")
print(res1,res2) 

3.服务端合法性校验流程

客户端加密字符串发送到服务端, 服务端结束并与服务端加密的字符串进行校验,真假

客户端
# ### 服务端1
import socket
import hmac

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

# 处理收发数据的逻辑
def auth(secret_key):
	msg = sk.recv(32)
	# hmac.new(key(盐),msg(密码))
	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 = "芝麻开门吧小怪怪"
res = auth(secret_key)
print(res , type(res))

""""""
if res == "True" :
	print("服务端校验成功~")
else:
	print("服务端校验失败~")

sk.close()
服务端
# ### 服务端2
import socketserver
import os
import hmac

class MyServer(socketserver.BaseRequestHandler):
	secret_key = "芝麻开门吧小怪怪"
	
	def auth(self):
		conn = self.request
		# 创建一个随机的32位字节流
		msg = os.urandom(32)
		# 把字节流发送给客户端
		conn.send(msg)
		# 服务端接受客户端发送过来的结果
		cli_res = conn.recv(1024).decode()
		
		# 服务端进行数据加密
		hm = hmac.new(self.secret_key.encode() , msg)
		# 获取服务端校验的数据结果
		ser_res = hm.hexdigest()
		
		# 让客户端和服务端的结果做校验
		return "True" if cli_res == ser_res else "False"

	def handle(self):
		# 获取校验结果
		res = self.auth()
		# 把结果发送给对应的客户端
		self.request.send(res.encode())

# ThreadingTCPServer多线程TCP服务
server = socketserver.ThreadingTCPServer( ("127.0.0.1" , 8003) , MyServer )
server.serve_forever()

原文地址:https://www.cnblogs.com/jia-shu/p/14204146.html