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)——博客园