一、课题名称
基于Python的非对称加密与对称加密相结合的文件传输系统设计与实现
二、课题背景与研究意义
在当前数字信息社会中,文件传输的安全性成为亟需解决的关键问题。尤其在网络环境下,文件在传输过程中可能会被窃听、篡改或伪造,因此如何实现安全、可靠、高效的文件加密传输成为研究热点。
对称加密算法(如AES)具有加密速度快、效率高的优点,但密钥分发困难;非对称加密算法(如RSA)则在密钥交换和身份认证方面具备天然优势,但加解密效率低下。为此,结合非对称加密和对称加密的“混合加密”模式被广泛采用,能够兼顾安全性与性能,已成为实际加密通信系统(如SSL/TLS)的主流结构。
本设计以Python语言为开发平台,设计并实现一个融合RSA与AES算法的文件安全传输系统,具备跨平台性强、结构清晰、用户界面友好等特点,适合教育、企业等多种应用场景,具有良好的学习和实践价值。
三、国内外研究现状
目前主流安全传输协议如HTTPS、SFTP、IPSec等大多采用混合加密机制实现文件传输安全控制。在高校、企业以及开源社区,也有不少关于Python加密传输的项目,但大多缺乏图形界面或结构过于复杂,不适合本科教学与研究。通过本设计,可以将密码学理论与实际编程技能结合,促进应用型人才培养。
四、课题目标与内容
(一)设计目标:
实现一个可运行的文件传输系统,支持局域网内加密传输;
融合非对称加密(RSA)与对称加密(AES)机制;
实现基本的密钥管理、文件加密传输、图形界面交互;
保障数据的机密性、完整性和安全性。
(二)系统功能结构:
密钥管理模块
生成RSA密钥对,用于加密AES密钥;
使用AES密钥对文件数据进行加密/解密;
支持CBC模式加密、PKCS#7填充。
文件传输模块
客户端与服务端基于Socket通信实现文件传输;
客户端加密AES密钥发送,服务端解密并接收文件数据;
支持断开自动关闭连接、异常处理等功能。
图形用户界面(GUI)模块
使用Tkinter实现客户端和服务端界面;
支持文件选择、传输进度条、日志提示;
启动/关闭服务器控制、发送文件操作一键完成。
五、关键技术与实现方法
非对称加密算法(RSA):用于客户端安全地将AES密钥加密并发送给服务端。使用 Cryptodome.PublicKey 实现密钥生成与加密/解密。
对称加密算法(AES):对文件内容进行加密,提升效率。采用CBC模式,确保安全性。
Socket网络编程:使用Python原生socket库,实现客户端-服务端双向通信。
Tkinter图形界面:提升系统易用性,实现用户友好的操作界面。
多线程技术:服务端采用线程并发模型,应对多客户端请求。
六、预期成果
一个完整可运行的Python文件加密传输系统;
RSA/AES加密流程源码与文档;
图形化客户端与服务器界面;
系统说明书、用户手册、测试报告等配套材料;
支持局域网通信、数据安全保护、传输日志打印等功能。
七、研究进度安排
第1-2周查阅资料、确定选题、撰写开题报告
第3-4周搭建基本Socket通信架构、测试连接稳定性
第5-6周实现RSA/AES加密模块、调试加密解密流程
第7-8周实现客户端文件上传与服务端接收逻辑
第9-10周集成图形用户界面(Tkinter)
第11-12周完善异常处理、支持多线程、优化系统性能
第13-14周系统测试、撰写说明书与论文初稿
第15-16周完善论文、准备答辩材料、模拟答辩
八、参考文献
William Stallings.《密码学与网络安全》. 清华大学出版社, 2021
RFC 3447: Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications
Python官方文档:socket — Low-level networking interface — Python 3.13.5 documentation
PyCryptodome文档:Welcome to PyCryptodome’s documentation — PyCryptodome 3.23.0 documentation
王珊,萨师煊.《数据库系统概论》第5版. 高等教育出版社,2015
核心代码参考案例:
系统概述
本设计实现了一个结合非对称加密(RSA)和对称加密(AES)的文件安全传输系统,兼顾了安全性与性能。系统使用RSA算法进行密钥交换和身份验证,使用AES算法进行高效的文件加密传输。
核心模块设计
1. 密钥管理模块
import os
from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import PKCS1_OAEP, AES
from Cryptodome.Random import get_random_bytes
import base64
import hashlib
class KeyManager:
@staticmethod
def generate_rsa_key_pair(key_size=2048):
"""生成RSA密钥对"""
key = RSA.generate(key_size)
private_key = key.export_key()
public_key = key.publickey().export_key()
return private_key, public_key
@staticmethod
def generate_aes_key(key_size=32):
"""生成AES密钥"""
return get_random_bytes(key_size)
@staticmethod
def encrypt_with_rsa(public_key, data):
"""使用RSA公钥加密数据"""
rsa_key = RSA.import_key(public_key)
cipher_rsa = PKCS1_OAEP.new(rsa_key)
return cipher_rsa.encrypt(data)
@staticmethod
def decrypt_with_rsa(private_key, encrypted_data):
"""使用RSA私钥解密数据"""
rsa_key = RSA.import_key(private_key)
cipher_rsa = PKCS1_OAEP.new(rsa_key)
return cipher_rsa.decrypt(encrypted_data)
@staticmethod
def encrypt_with_aes(key, data):
"""使用AES加密数据"""
iv = get_random_bytes(AES.block_size)
cipher_aes = AES.new(key, AES.MODE_CBC, iv)
encrypted = cipher_aes.encrypt(pad(data, AES.block_size))
return iv + encrypted
@staticmethod
def decrypt_with_aes(key, encrypted_data):
"""使用AES解密数据"""
iv = encrypted_data[:AES.block_size]
cipher_aes = AES.new(key, AES.MODE_CBC, iv)
return unpad(cipher_aes.decrypt(encrypted_data[AES.block_size:]), AES.block_size)
def pad(data, block_size):
"""填充数据到块的整数倍"""
padding_length = block_size - len(data) % block_size
return data + bytes([padding_length] * padding_length)
def unpad(data, block_size):
"""移除填充数据"""
padding_length = data[-1]
return data[:-padding_length]
2. 文件加密传输模块
import socket
import json
from threading import Thread
class FileTransferServer:
def __init__(self, host='0.0.0.0', port=5000):
self.host = host
self.port = port
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.private_key, self.public_key = KeyManager.generate_rsa_key_pair()
def start(self):
"""启动服务器"""
self.server_socket.bind((self.host, self.port))
self.server_socket.listen(5)
print(f"Server listening on {self.host}:{self.port}")
while True:
client_socket, addr = self.server_socket.accept()
print(f"Connection from {addr}")
client_thread = Thread(target=self.handle_client, args=(client_socket,))
client_thread.start()
def handle_client(self, client_socket):
"""处理客户端连接"""
try:
# 1. 发送服务器的公钥给客户端
client_socket.send(self.public_key)
# 2. 接收客户端使用服务器公钥加密的AES密钥
encrypted_aes_key = client_socket.recv(2048)
aes_key = KeyManager.decrypt_with_rsa(self.private_key, encrypted_aes_key)
# 3. 接收加密的文件信息
encrypted_info = client_socket.recv(1024)
file_info = json.loads(KeyManager.decrypt_with_aes(aes_key, encrypted_info).decode())
# 4. 接收加密的文件数据
file_data = b''
while True:
chunk = client_socket.recv(4096)
if not chunk:
break
file_data += chunk
# 5. 解密文件数据
decrypted_data = KeyManager.decrypt_with_aes(aes_key, file_data)
# 6. 保存文件
save_path = os.path.join('received_files', file_info['filename'])
os.makedirs('received_files', exist_ok=True)
with open(save_path, 'wb') as f:
f.write(decrypted_data)
print(f"File {file_info['filename']} received and saved successfully.")
except Exception as e:
print(f"Error handling client: {e}")
finally:
client_socket.close()
class FileTransferClient:
def __init__(self, host='localhost', port=5000):
self.host = host
self.port = port
self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def send_file(self, filepath):
"""发送文件到服务器"""
try:
self.client_socket.connect((self.host, self.port))
# 1. 接收服务器的公钥
server_public_key = self.client_socket.recv(4096)
# 2. 生成AES密钥并用服务器公钥加密
aes_key = KeyManager.generate_aes_key()
encrypted_aes_key = KeyManager.encrypt_with_rsa(server_public_key, aes_key)
self.client_socket.send(encrypted_aes_key)
# 3. 读取并加密文件
with open(filepath, 'rb') as f:
file_data = f.read()
filename = os.path.basename(filepath)
file_info = json.dumps({
'filename': filename,
'filesize': len(file_data)
}).encode()
# 4. 加密文件信息并发送
encrypted_info = KeyManager.encrypt_with_aes(aes_key, file_info)
self.client_socket.send(encrypted_info)
# 5. 加密文件数据并发送
encrypted_data = KeyManager.encrypt_with_aes(aes_key, file_data)
self.client_socket.sendall(encrypted_data)
print(f"File {filename} sent successfully.")
except Exception as e:
print(f"Error sending file: {e}")
finally:
self.client_socket.close()
3. 用户界面模块
import tkinter as tk
from tkinter import filedialog, messagebox
from tkinter.ttk import Progressbar
class FileTransferGUI:
def __init__(self, root):
self.root = root
root.title("安全文件传输系统")
root.geometry("500x300")
# 服务器控制区域
server_frame = tk.LabelFrame(root, text="服务器控制", padx=5, pady=5)
server_frame.pack(fill="x", padx=10, pady=5)
self.start_server_btn = tk.Button(
server_frame, text="启动服务器", command=self.start_server)
self.start_server_btn.pack(side="left", padx=5)
self.stop_server_btn = tk.Button(
server_frame, text="停止服务器", state="disabled", command=self.stop_server)
self.stop_server_btn.pack(side="left", padx=5)
# 客户端区域
client_frame = tk.LabelFrame(root, text="文件传输", padx=5, pady=5)
client_frame.pack(fill="x", padx=10, pady=5)
self.file_path = tk.StringVar()
tk.Entry(client_frame, textvariable=self.file_path, width=40).pack(
side="left", padx=5)
tk.Button(client_frame, text="浏览...", command=self.browse_file).pack(
side="left", padx=5)
tk.Button(client_frame, text="发送文件", command=self.send_file).pack(
side="left", padx=5)
# 状态区域
status_frame = tk.Frame(root)
status_frame.pack(fill="x", padx=10, pady=5)
self.status_label = tk.Label(status_frame, text="就绪")
self.status_label.pack(side="left")
self.progress = Progressbar(root, orient="horizontal",
length=200, mode="determinate")
self.progress.pack(pady=10)
# 服务器实例
self.server = None
self.server_thread = None
def browse_file(self):
filename = filedialog.askopenfilename()
if filename:
self.file_path.set(filename)
def start_server(self):
self.server = FileTransferServer()
self.server_thread = Thread(target=self.server.start)
self.server_thread.daemon = True
self.server_thread.start()
self.start_server_btn.config(state="disabled")
self.stop_server_btn.config(state="normal")
self.status_label.config(text="服务器已启动")
def stop_server(self):
if self.server:
self.server.server_socket.close()
self.start_server_btn.config(state="normal")
self.stop_server_btn.config(state="disabled")
self.status_label.config(text="服务器已停止")
def send_file(self):
filepath = self.file_path.get()
if not filepath:
messagebox.showerror("错误", "请选择要发送的文件")
return
client = FileTransferClient()
Thread(target=client.send_file, args=(filepath,)).start()
self.status_label.config(text="文件发送中...")
self.progress["value"] = 0
# 模拟进度条
for i in range(5):
self.root.after(i*200, lambda i=i: self.progress.step(20))
self.root.after(1000, lambda: self.status_label.config(text="文件发送完成"))
self.root.after(1000, lambda: self.progress["value"] = 0)
def main():
root = tk.Tk()
app = FileTransferGUI(root)
root.mainloop()
if __name__ == "__main__":
main()
系统特点
混合加密机制:结合RSA和AES的优势,RSA用于安全交换AES密钥,AES用于高效加密文件数据
安全性:
使用PKCS#1 OAEP填充方案增强RSA安全性
每次会话使用不同的AES密钥
实现CBC模式和适当的填充方案
完整性:通过文件大小验证确保数据传输完整
用户友好:提供图形界面便于操作



















暂无评论内容