20213401 实验三《Python程序设计》实验报告

学号 20213401王尊阳 《Python程序设计》实验3报告

课程:《Python程序设计》
班级:2134
姓名:王尊阳
学号:20213401
实验教师:王志强
实验日期:2022年4月21日
必修/选修: 公选课

1.实验内容

创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套接字(TCP/UDP)进行通信。

2.实验要求

创建服务端和客户端,选择一个通信端口,用Python语言编程实现通信演示程序;
要求包含文件的基本操作,例如打开和读写操作。
要求发送方从文件读取内容,加密后并传输;接收方收到密文并解密,保存在文件中。
程序代码托管到码云。

3. 实验过程及结果

3.1 代码
客户端

import socket
import binascii
from pyDes import des, CBC, PAD_PKCS5
import socket      
import datetime#以当前日期加密  
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
class AesCrypto():
    def __init__(self, key, IV):
        self.key = key #需为16位倍数
        self.iv = IV #必须为16位
        self.mode = AES.MODE_CBC
    def encrypt(self, text):
        cryptor = AES.new(self.key, self.mode, self.iv)
        length = 16
        count = len(text)
        if(count%length != 0):
            add = length-(count%length)
        else:
            add=0

        text = text+("\0".encode()*add)#因为中文位数原因,这里需要.encode

        self.ciphertext = cryptor.encrypt(text)
        return (self.ciphertext)
    
    def decrypt(self, text):
        cryptor = AES.new(self.key, self.mode, self.iv)
        plain_text = cryptor.decrypt((text)).decode()
        return plain_text

def des_encrypt(secret_key, s):
    iv = secret_key
    k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
    en = k.encrypt(s, padmode=PAD_PKCS5)
    return binascii.b2a_hex(en)

def des_decrypt(secret_key, s):
    iv = secret_key
    k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
    de = k.decrypt(binascii.a2b_hex(s), padmode=PAD_PKCS5)
    return de
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print("欢迎来到客户端")
s.connect(('localhost',8001)) #暂时本地传输本地
mo = input("请选择模式\n1.AES加密2.DES加密:")
if mo== '1':
    s.sendall(mo.encode())
    str1 = input("请输入传输内容:")
    k = datetime.date.today()
    key1 = k.__format__('%Y&%m&%d%j%U%w').encode()
    mo1 = AesCrypto(key=key1, IV=key1)
    str1 = mo1.encrypt(str1.encode())
    s.sendall(str1)
    data = s.recv(1024)
    print(data.decode())
if mo=='2':
    s.sendall(mo.encode())
    str1=input("请输入要传输的内容:")
    secret_str = des_encrypt('12345678', str1)
    secret_str = str(secret_str, encoding = "utf-8")  
    print(secret_str)
    s.sendall(secret_str.encode())
    data=s.recv(1024)
    print(data.decode())
s.close()     

服务器

import socket
import binascii
import pyDes
from pyDes import des, CBC, PAD_PKCS5     
import datetime  
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
def des_encrypt(secret_key, s):
    iv = secret_key
    k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
    en = k.encrypt(s, padmode=PAD_PKCS5)
    return binascii.b2a_hex(en)

def des_decrypt(secret_key, s):
    iv = secret_key
    k = des(secret_key, CBC, iv, pad=None, padmode=PAD_PKCS5)
    de = k.decrypt(binascii.a2b_hex(s), padmode=PAD_PKCS5)
    return de
class AesCrypto():
    def __init__(self, key, IV):
        self.key = key
        self.iv = IV
        self.mode = AES.MODE_CBC
    def encrypt(self, text):
        cryptor = AES.new(self.key, self.mode, self.iv)
        length = 16
        count = len(text)
        if(count%length != 0):
            add = length-(count%length)
        else:
            add=0

        text = text+("\0".encode()*add)

        self.ciphertext = cryptor.encrypt(text)
        return (self.ciphertext)
    
    def decrypt(self, text):
        cryptor = AES.new(self.key, self.mode, self.iv)
        plain_text = cryptor.decrypt((text)).decode('utf8','ignore')
        return plain_text
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("localhost", 8001))
s.listen()
con,addr= s.accept()
mo = con.recv(1024)
if mo.decode()== '1':
    print("已收到文字传输请求,对方正在输入...")
    data = con.recv(1024)
    k = datetime.date.today()
    key1 = k.__format__('%Y&%m&%d%j%U%w').encode()
    mo1 = AesCrypto(key=key1, IV=key1)
    data = mo1.decrypt(data)
    print(data)
    right = "信息已收到"
    con.sendall(right.encode())

elif mo.decode()=='2':
    data=con.recv(1024)
    print(data.decode())
    con.sendall(("服务器已经接受到数据内容:"+str(data.decode())).encode())
    clear_str = des_decrypt('12345678', data.decode())
    print(str(clear_str, encoding = "utf-8"))  
s.close()

测试截图

上传gitee截图

4. 实验过程中遇到的问题和解决过程

问题1:des加密方式无法加密中文
问题1解决方案:采用了另一种加密方式aes,阅读相关文章并咨询对这方面有所了解的同学、老师
问题2:错误“UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte 0xca in position 0: invalid continuation byte”
问题2解决方案:询问老师,并采用utf-8方式
问题3:pyDes模块显示无法调用
问题4解决方案:在老师的帮助下,使用mark root dictionary

其他(感悟、思考等)

这次实验中,我在aes加解密和des加解密上下了很大的功夫,从最初的啥都看不懂到逐步理解,学习的过程十分痛苦,不仅需要寻求老师帮助,更是自己的一种耐心学习,只有自己想学,才能真正去接受。学会搜寻资料是我要磨炼自己的重要途径,比如说在安装Crypto模块时,老师安装完显示无法调用,当我去搜索了相关资料后,才理解模块安装错了。
文件内容的传输是一个很要命的工作,不知道为什么,文字输入明明可以正常运行,但一到文件内容传输就老报错,而且文件读取方式也很复杂 ,自己得反复去揣测才能明白其中的工作原理。

参考资料

DES加密方法——微信老师所发资料
AES加密算法的python版本,基于pycrypto库
python字符编码(UTF-8)——博客园

posted @ 2022-04-27 22:43  小甲鱼本鱼  阅读(112)  评论(0编辑  收藏  举报