实验目的
- 设计安全的信息传输工具,解决网络传输涉密文件过程中的安全性问题。安全的信息传输,涉及多个密码学知识点,在实验设计过程中,不断加深理解密码学基本概念和算法基础原理,并且能够锻炼独立的代码编写能力和知识的综合运用能力。
实验仪器或设备
- 硬件:计算机1台
- 操作系统:Windows 10
- 软件/平台:Visual Studio Code、QT
- 编程语言:Python
实验内容
设计与实现一款局域网中点到点(即一台计算机到另外一台计算机)的信息传输工具,要求能够保证信息在传输过程中的保密性、完整性和发送/接收方的不可否认性,以防止通信线路上的窃听、泄露、破坏、篡改等不良操作。
- 采用对称与非对称混合加密方法,每进行一次通信,更改一次会话密钥(用于信息加密的对称密钥)。
- 能够实现对任意类型的文件进行安全传输。
- 可采用适当的开发语言和开发工具。
- 软件用户界面友好,提示信息完整,操作舒适。
- 提交实验报告、包括分析和设计文档及代码清单。
- 平台不限。linux/windows/android
实验步骤
设计思路+设计文档
** 开发语言、开发平台、开发工具模块的选择**
该实验要求为设计完成一款文件安全传输软件,前端要求界面友好操作舒适,功能要求实现通信、加密、传输。综合考虑,选择使用Python作为开发语言。因为Python自身带有许多常用工具模块,且用于加密解密的安全库、用于通信传输的socket库也齐全,因此非常方便用于开发软件,结合使用可以节约开发时间,减少代码量。本人常用于编写Python的IDE为Visual Studio Code,因此本实验也通过VS Code完成。因为使用Python编程,所以软件界面设计选择使用Python库PyQt5,不过需要另外安装。PyQt是一个创建GUI应用程序的工具包。它是Python编程语言和Qt库的成功融合。Qt库是目前最强大的库之一。
总结如下:
- 通信、传输:socket库
- DES加密解密:pyDes库或Crypto库
- RSA加密解密:rsa库
- MD5哈希:md5库(可选,因为rsa库本身也有签名+摘要+验签的功能)
- 软件界面:PyQt5库(包含界面设计、多线程等)
- 常用库:random(生成随机数)、os(文件操作)、re(正则表达式)、json(编解码)、sys(系统操作)、threading(多线程)、time(时间)等
开发顺序与大致框架
主要顺序是先前端再后端。设计好前端界面后,可以对应前端界面的按键、内容显示等部署后端功能,方便操作;相反,如果先完成后端功能,再设计前端界面,有可能出现前后端功能不匹配的问题,或是要重复修改后端功能,无疑增加了工作量。
前端部分,即软件界面设计。根据实验对于软件的功能要求,需要设计出与用户交互的按键、输入框,以及内容显示栏、提示框等。具体包括:发送键、接收键、取消键、IP地址输入框、端口选择框、文件选择栏、接收文件信息反馈栏、状态提示框、页面切换键、进度条等。
后端部分,即功能实现,可根据实验提供的“文件安全传输流程”图完成。实现顺序:
- 启动前端界面,主线程。包含实现按键函数、读取输入信息、显示提示信息。
- 服务端(监听+发送方)与客户端(请求+接收方)的通信,分为服务端一个新的通信线程和客户端一个新的通信线程。包含通信连接、生成密钥、密钥交换的操作。
- 服务端与客户端的信息传输,分为服务端一个新的发送线程和客户端一个新的接收线程。包含加/解密文件、生成摘要、签名、打包文件、发送/接收的操作。
自定义要素和功能
- 将“单文件安全传输”优化为了“多文件安全传输”。
- 发送文件前首先发送文件头,其中包含文件名和文件大小等属性。
- 文件接收后反馈文件接收状态后再继续发送下一文件,以确保是否需要重传。
实验分析(分析为什么这样设计、安排)
“单文件安全传输”=>“多文件安全传输”
实验中没有明确要求是单文件传输或是多文件传输,考虑到软件设计要人性化,我才设定为“多文件安全传输”,可以一次性选择多文件进行安全发送。
** 主线程和分线程**
主线程运行软件窗口界面,而分线程分为了4个:服务端连接线程、客户端连接线程、服务端发送线程、客户端接收线程,分别负责实现不同的功能。
之所以要多线程运行,是由于等待连接和等待传输的过程如果放在主线程中,会造成界面假死的状态,因此为了避免这种情况发生,采用多线程方式来运行通信连接和文件传输的步骤。
文件头传输
发送文件之前会先发送文件头,文件头中包含文件名和文件大小以及当前传输状态(正常、完成、出错)。
文件头是提前告知接收方的信息。文件名用于接收文件的命名;文件大小让接收方获知需要接收多少的数据;当前传输状态让接收方获知多文件传输是否传输完成。
文件接收状态反馈
接收方在接收完文件后需要对文件进行数据完整性的检验(即对比摘要内容),当比对结果出现错误,即表示当前接收的文件可能被篡改,当前通信并不安全,需要重新生成密钥并交换,建立新的安全通信连接。
由于我将“单文件安全传输”优化为了“多文件安全传输”,因此发送方不能够一次将全部文件都发送给接收方,而应该等待接收方对当前文件作出反馈,表示该文件数据完整性是否良好,再进一步发送下一个文件,否则重新建立连接并重传该文件。
实验过程与结果
实验过程
界面设计
界面设计使用Qt平台,Qt平台中提供有图形化界面进行界面设计,十分方便。如下图为“发送文件”界面的设计图。
如下图为“接收文件”界面的设计图。
另存为文件“file.ui”。
界面(前端)代码生成
Python中提供pyuic5工具,可以将file.ui的界面布局文件转换成Python代码,免去了繁琐的敲代码生成界面的过程。命令为“pyuic5 -o file.py file.ui”表示源文件为file.ui生成目标文件file.py。请注意,此时生成的代码file.py仅仅实现了界面显示,并未实现软件后端的功能。
编写(后端)功能代码
前端代码生成后,根据前端界面的控件名称,在后端代码实现通信传输功能的同时控制前端界面显示相应内容。
程序打包
代码编写后的文件为.py文件,可以使用Python工具PyInstaller,将代码以及相关依赖库打包成.exe程序文件。命令为“pyinstaller -F -i favicon.ico run.py -w”,-F表示打包为单文件程序,-i表示绑定程序图标为favicon.ico,run.py为主程序代码,-w表示程序运行时不显示命令行窗口。具体过程如下:
实验代码清单+关键代码分析
代码清单
- run.py:主程序代码,负责生成软件主窗口,以及各种按键函数。还包含四个分线程类(服务器连接、客户端连接、服务器发送、客户端接收)。
- sendfile.py:发送操作类,包含所有的发送文件操作。
- recfile.py:接收操作类,包含所有的接收文件操作
- des.py:DES加解密操作。
- rsa1.py:RSA加解密操作。
- md5.py(可选):MD5哈希操作。
- utility.py:其他工具函数,如生成目录、生成随机数、判断输入内容是否为IP地址。
- file.py:file.ui生成的界面代码,由run.py运行启动。
- 注1:代码文件中有详细的代码注释,可以直接查看代码文件进行阅读。
关键代码分析
- sendfile.py的Sender类的sendPro函数
- 函数首先判断当前是否是重传文件的操作,若是,则恢复到之前的状态。
- for循环遍历需要上传的文件。
- 使用DES生成DES密钥的同时,加密当前文件。
- packupFile函数中包含RSA加密DES密钥、MD5哈希生成文件摘要、打包文件的三个操作。
- 根据打包后的文件,生成相应的文件头