题目
模拟网络通信加密 (小计 20分)
模拟一个简单的网络通信场景,使用 Socket 编程和加密技术,在客户端和服务器之间传输加密数据。采用 RSA 非对称加密算法对会话密钥(如 AES 密钥)进行加密传输,然后使用会话密钥对实际通信数据进行 AES 加密,以此来演示非对称加密与对称加密结合在网络通信安全中的应用。
(1)编程语言自定,可以使用封装函数或其它开发库。
(2)编写客户端和服务器端的 程序,建立 Socket 连接。
(3)服务器生成一对 RSA 密钥(公钥和私钥),将公钥发送给客户端。
(4)客户端生成一个随机的 AES 会话密钥,使用服务器的公钥对其进行加密,并将加密后的会话密钥发送给服务器。
(5)服务器使用自己的私钥解密得到 AES 会话密钥。
(6)客户端和服务器使用 AES 会话密钥对传输的数据进行加密和解密。例如,客户端向服务器发送一段消息(如 “Hello, I am LiMing(以李明为例,请根据个人信息自行调整) !”),加密后发送,服务器接收并解密显示;服务器回复一段消息(如 “Welcome, LiMing! I am Server”),同样加密后发送,客户端接收并解密显示。
(7)确保在整个通信过程中,加密、解密操作与 Socket 通信的逻辑正确配合,处理可能出现的网络异常(如连接中断、超时等)。
(8)记录并分析通信过程中数据的加密、解密时间,以及传输的数据量变化情况。
(评分参考: (1)未实现RSA密钥对进行加密与解密的,减5分; (2) 未传递 AES密钥的减5分 (3)未使用AES密钥实现会话通信的减 5分;(4)未在通信中使用个人信息的,减5分。 其它功能的完整性,酌情减分。 本任务最多扣20分)
实验环境
操作系统:Windows 11
编程语言:Python 3.11
开发工具:PyCharm
依赖库:rsa等,依赖库的安装可参考任务二。
代码实现
server.py
import socket
import rsa
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import time
# 生成 RSA 密钥对(公钥和私钥)
(pubkey, privkey) = rsa.newkeys(2048)
# 设置服务器地址和端口
host = 'localhost'
port = 12345
# 创建 Socket 并绑定端口
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((host, port))
server_socket.listen(1)
print('等待连接...')
print(f"服务器正在监听 {host}:{port}...")
conn, addr = server_socket.accept()
print(f'连接来自 {addr}')
# 发送公钥给客户端
pubkey_pem = pubkey.save_pkcs1()
conn.sendall(pubkey_pem)
# 接收加密的 AES 密钥
encrypted_aes_key = conn.recv(4096)
# 解密 AES 密钥(服务器使用自己的私钥解密得到 AES 会话密钥)
start_time = time.time()
aes_key = rsa.decrypt(encrypted_aes_key, privkey)
end_time = time.time()
print(f'RSA 解密 AES 密钥耗时: {end_time - start_time} 秒')
# 创建 AES 加密器
cipher = AES.new(aes_key, AES.MODE_ECB)
# 接收客户端消息并解密
encrypted_data = conn.recv(4096)
start_time = time.time()
decrypted_data = unpad(cipher.decrypt(encrypted_data), AES.block_size)
end_time = time.time()
print(f'AES 解密消息耗时: {end_time - start_time} 秒')
print(f'服务器收到的消息: {decrypted_data.decode()}')
# 服务器回复消息
message = 'Welcome, LiMing! I am Server'
start_time = time.time()
encrypted_response = cipher.encrypt(pad(message.encode(), AES.block_size))
end_time = time.time()
print(f'AES 加密消息耗时: {end_time - start_time} 秒')
conn.sendall(encrypted_response)
# 关闭连接
conn.close()
server_socket.close()
client.py
import socket
import rsa
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import os
import time
# 设置服务器地址和端口
host = 'localhost'
port = 12345
# 创建 Socket 并连接服务器
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((host, port))
# 生成随机的 AES 会话密钥
aes_key = os.urandom(16)
# 接收服务器的公钥
pubkey_pem = client_socket.recv(4096)
pubkey = rsa.PublicKey.load_pkcs1(pubkey_pem)
# 使用服务器的公钥加密 AES 密钥
start_time = time.time()
encrypted_aes_key = rsa.encrypt(aes_key, pubkey)
end_time = time.time()
print(f'RSA 加密 AES 密钥耗时: {end_time - start_time} 秒')
# 发送加密的 AES 密钥给服务器
client_socket.sendall(encrypted_aes_key)
# 创建 AES 加密器
cipher = AES.new(aes_key, AES.MODE_ECB)
# 客户端发送消息
message = 'Hello, I am LiMing!'
start_time = time.time()
encrypted_data = cipher.encrypt(pad(message.encode(), AES.block_size))
end_time = time.time()
print(f'AES 加密消息耗时: {end_time - start_time} 秒')
client_socket.sendall(encrypted_data)
# 接收服务器回复并解密
encrypted_response = client_socket.recv(4096)
start_time = time.time()
decrypted_response = unpad(cipher.decrypt(encrypted_response), AES.block_size)
end_time = time.time()
print(f'AES 解密消息耗时: {end_time - start_time} 秒')
print(f'服务器回复的消息: {decrypted_response.decode()}')
# 关闭连接
client_socket.close()