06,验证客户端的合法性

1,合法性验证

登录图解

两种加密方法

# 生成一个随机的字符串

import os
import hashlib


ret = os.urandom(32)        # 随机生成一个32位的字符串
key = '411528'.encode('utf-8')      # 这个是秘钥,不能通过网络传输
sha = hashlib.sha1(key)             # 进行哈希加密
sha.update(ret)
ret = sha.hexdigest()               # 进行特殊算法进行加密
print(ret)

import hmac     # 可以替代hashlib模块的,更加简便,专门用于网络安全算法的摘要模块
h = hmac.new(b'41152', os.urandom(32))
ret = h.digest()
print(ret)

client.py

import hashlib
import socket


secret_key = b'4115281'
sk = socket.socket()
sk.connect(('127.0.0.1', 9000))


rand = sk.recv(32)      # 接收服务端发送的随机字符串

sha = hashlib.sha1(secret_key)      # 根据字符串和秘钥进行加密计算
sha.update(rand)
res = sha.hexdigest()

sk.send(res.encode('utf-8'))        # 将加密结果发送给服务端

# 继续和server端进行通信
msg = sk.recv(1024).decode('utf-8')
print(msg)

server.py

import os
import socket
import hashlib

secret_key = b'411528'
sk = socket.socket()
sk.bind(('127.0.0.1', 9000))
sk.listen()

conn, addr = sk.accept()

random_str = os.urandom(32)        # 创建一个随机的字符串
rand = random_str
conn.send(rand)

sha = hashlib.sha1(secret_key)      # 根据字符串和秘钥进行加密计算
sha.update(rand)
res = sha.hexdigest()

res_client = conn.recv(1024).decode('utf-8')       # 等待接收客户端的结果

if res == res_client:
    print('是合法的客户端')
    conn.send(b'Hello')

else:
    conn.send('非法客户端'.encode('utf-8'))
    conn.close()        # 如果不一致,立即断开连接

2,练习

登录下载 + 文件下载
    用户必须登录才能下载
    用户是否登录应该记录在服务器
    用户可以自己选择上传还是下载

__init__.py

import hashlib


def get_md5(username, password):
    md5 = hashlib.md5(username.encode('utf-8'))
    md5.update(password.encode('utf-8'))
    return md5.hexdigest()

ret = get_md5('alex', '3714')        # 这里已经设置了用户名和密码
print(ret)

client.py

import json
import sys
import socket
import struct


def dowmload(sk):
    opt_dic = {'operate':'download'}
    my_send(sk, opt_dic)
    msg = my_recv(sk)
    with open(msg['filename'], 'wb') as f:
        while msg['filesize'] > 0:
            content = sk.recv(1024)
            msg['filesize'] -= len(content)
            f.write(content)


def my_recv(sk):
    msg_len = sk.recv(4)
    dict_len = struct.unpack('i', msg_len)[0]
    msg = sk.recv(dict_len).decode('utf-8')
    msg = json.loads(msg)
    return msg


def my_send(sk, dic):
    str_dic = json.dumps(dic)
    b_dic = str_dic.encode('utf-8')
    mlen = struct.pack('i', len(b_dic))
    sk.send(mlen)
    sk.send(b_dic)


def login(sk):
    while True:
        usr = input('用户名:').strip()
        pwd = input('密 码:').strip()
        dic = {'username': usr, 'password': pwd}
        my_send(sk, dic)
        ret = my_recv(sk)
        if ret['operate'] == 'login' and ret['result']:
            print('登录成功!')
            break
        else:
            print('登录失败!')

# 发送
sk = socket.socket()
sk.connect(('127.0.0.1', 9001))
# 登录
login(sk)
# 上传/下载
opt_lst = ['upload', 'download']
for index, opt in enumerate(opt_lst, 1):
    print(index, opt)
num = int(input('请选择要操作的序号:'))
getattr(sys.modules[__name__], opt_lst[num-1])(sk)      # 反射的内容

sk.close()

server.py

import socket
import struct
import json
import os.path
import hashlib
import sys


def my_send(conn, dic):
    str_dic = json.dumps(dic)
    b_dic = str_dic.encode('utf-8')
    mlen = struct.pack('i', len(b_dic))
    conn.send(mlen)
    conn.send(b_dic)


def dowmload():
    abs_path = r'C:\Users\yt158\Pictures\Camera Roll\101680360b4ffbd805c4f45bb7d288b.jpg'
    filename = os.path.basename(abs_path)
    filesize = os.path.getsize(abs_path)
    dic = {'filename': filename, 'filesize': filesize}
    my_send(conn, dic)
    with open(abs_path, mode='rb') as f:
        while filesize > 0:
            content = f.read(1024)
            filesize -= len(content)
            conn.send(content)


def my_recv(conn):
    msg_len = conn.recv(4)
    dict_len = struct.unpack('i', msg_len)[0]
    msg = conn.recv(dict_len).decode('utf-8')
    msg = json.loads(msg)
    return msg


def get_md5(username, password):
    md5 = hashlib.md5(username.encode('utf-8'))
    md5.update(password.encode('utf-8'))
    return md5.hexdigest()


def login(conn):
    flag = True
    while flag:
        msg = my_recv(conn)
        with open('userinfo') as f:
            for line in f:
                name, pwd = line.strip().split('|')
                if name == msg['username'] and pwd == get_md5(name, msg['password']):
                    res, flag = True, False
                    break
            else:
                res = False
            dic = {'operate': 'login', 'result': res}
            my_send(conn, dic)

sk = socket.socket()
sk.bind(('127.0.0.1', 9001))
sk.listen()

conn, _ = sk.accept()

# 有一个客户端来连接你
# 登录
login(conn)

# 接收消息,根据用户选择上传/下载
opt_dic = my_recv(conn)
if hasattr(sys.modules[__name__], opt_dic['operate']):      # 使用反射
    getattr(sys.modules[__name__], opt_dic['operate'])()


conn.close()
sk.close()

更多内容可以查看自己学python的过程,简单笔记。-CSDN博客

更多内容可以查看自己学python的过程,简单笔记。-CSDN博客

更多内容可以查看自己学python的过程,简单笔记。-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值