20242317 2024-2025-2 《Python程序设计》实验三报告

20242317 2024-2025-2 《Python程序设计》实验三报告

课程:《Python程序设计》
班级:2423
姓名:林楚皓
学号:20242317
实验教师:王志强
实验日期:2025年4月16日
必修/选修:公选课

一、实验内容

创建服务端和客户端,服务端在特定端口监听多个客户请求。客户端和服务端通过Socket套接字(TCP/UDP)进行通信。
具体要求如下:
1.创建服务端和客户端,选择一个通信端口,用Python语言编程实现通信演示程序;
2.要求包含文件的基本操作,例如打开和读写操作。
3.要求发送方从文件读取内容,加密后并传输;接收方收到密文并解密,保存在文件中。
4.程序代码托管到码云。

二、实验过程及结果

(一)了解AES加解密算法

群里老师发的加密和解密的部分代码如下:

import socket
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import os

# 加密密钥,必须是16、24或32字节
key = os.urandom(16)
# 初始化向量,必须是16字节
iv = os.urandom(16)

def encrypt_message(message):
    cipher = AES.new(key, AES.MODE_CBC, iv)
    encrypted = cipher.encrypt(pad(message.encode('utf-8'), AES.block_size))
    return iv + encrypted

def decrypt_message(encrypted_message):
    iv = encrypted_message[:AES.block_size]
    encrypted = encrypted_message[AES.block_size:]
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted = unpad(cipher.decrypt(encrypted), AES.block_size)
    return decrypted.decode('utf-8')

通过检索相关资料,我了解到:AES(高级加密标准)加解密算法是一种对称加密算法,它将明文分成固定长度的块,通常为128位,然后使用密钥对这些块进行一系列复杂的变换,包括字节替换、行移位、列混淆和轮密钥加等操作,将明文加密成密文。解密过程则是加密的逆过程,使用相同的密钥对密文进行反向变换,还原出原始的明文。

(二)学习Python中的文件操作

1.运用open()函数打开文件,依据需求选择合适的打开模式。如:'r':只读模式(默认);'w':写入模式等;
2.利用write()方法写入文件内容;
3.使用with语句来管理文件能确保文件在使用完毕后自动关闭。
如:

file_path = 'example.txt'
# 读取文件
with open(file_path, 'r') as file:
    data = file.read()
    print(data)

(三)编写服务端Server代码

以下是服务端代码和一些必要的注释:

import socket
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad

# 加密密钥,必须是16、24或32字节
key = b'0123456789abcdef' # 与客户端保持一致
# 初始化向量,必须是16字节
iv = b'abcdef9876543210'   # 与客户端保持一致

def decrypt_message(encrypted_message):
    iv = encrypted_message[:AES.block_size]
    encrypted = encrypted_message[AES.block_size:]
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted = unpad(cipher.decrypt(encrypted), AES.block_size)
    return decrypted.decode('utf-8')

# 新建服务端Socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
address = ('localhost', 9999)
# 绑定
server_socket.bind(address)
# 监听
server_socket.listen(5)
print("开始监听....", address)

# 接受客户端连接
client_socket, address = server_socket.accept()
print("我们收到{}的连接".format(address))

# 接收客户端发送的加密消息
encrypted_message = client_socket.recv(1024)

# 解密消息
decrypted_message = decrypt_message(encrypted_message)
print("客户端说:", decrypted_message)

# 将解密后的内容保存到文件
with open("server_output.txt", "w", encoding="utf-8") as file:
    file.write(decrypted_message)

# 向客户端发送响应
client_socket.send("消息已接收并解密".encode("utf-8"))

# 关闭连接
client_socket.close()

(四)编写客户端Client代码

以下是客户端代码和一些必要的注释:

import socket
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad

# 加密密钥,必须是16、24或32字节
key = b'0123456789abcdef' # 与客户端保持一致
# 初始化向量,必须是16字节
iv = b'abcdef9876543210'   # 与客户端保持一致

def encrypt_message(message):
    cipher = AES.new(key, AES.MODE_CBC, iv)
    encrypted = cipher.encrypt(pad(message.encode('utf-8'), AES.block_size))
    return iv + encrypted

# 新建Socket,实例化
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接服务器
client_socket.connect(('localhost', 9999))

# 从文件读取内容
with open("client_input.txt", "r", encoding="utf-8") as file:
    message = file.read()

# 加密消息
encrypted_message = encrypt_message(message)
client_socket.send(encrypted_message)

# 接收服务端的响应
data = client_socket.recv(1024)
print("服务端回答:", data.decode("utf-8"))

client_socket.close()

(五)运行结果

1.在Server和Client代码文件所在文件夹创建文本文件client_input.txt,并输入要传输的内容,如“你好Python!”


2.先运行Server代码,后运行Client代码,运行结果如下:


3.打开所在文件夹,发现server_output.txt已经创建,并且内容已经解密并写入其中。

(六)上传Gitee

实验三:Socket编程技术 - Howardlch123/Python_work - Gitee.com

三、实验过程中遇到的问题和解决过程

  • 问题:Server程序与Client程序运行时,出现报错:
    服务端

    客户端

    自查代码,发现服务端和客户端的加密密钥设置和初始化向量均使用os.urandom()函数随机生成:
import socket
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import os

# 加密密钥,必须是16、24或32字节
key = os.urandom(16)
# 初始化向量,必须是16字节
iv = os.urandom(16)

这可能导致服务端和客户端的加解密密钥和初始化向量不匹配。

  • 问题解决方案:
    指定密钥和初始化向量,将客户端与服务端的密钥和向量保持一致。
# 加密密钥,必须是16、24或32字节
key = b'0123456789abcdef' # 与客户端保持一致
# 初始化向量,必须是16字节
iv = b'abcdef9876543210'   # 与客户端保持一致

参考资料

posted @ 2025-04-26 17:28  Howardlch123  阅读(52)  评论(0)    收藏  举报