安全即时通讯系统
一、课程设计目的
本次课程设计目的是了解大型程序开发设计时所需要的步骤及其基本原则,通过团队分工合作的方式,以实践为过程,认识了软件开发的过程模型和生命周期,并且在程序设计的途中, 充分体会团队合作中沟通交流、合理分工的重要性,学习将分工完成的内容整合形成一个完整的工程。
二、需求分析
1、系统功能:
我们站在程序使用者的角度,分析出用户所需要的功能,再结合程序设计要求,我们认为该系统需要具备以下功能:通过P2P和C/S混合架构实现即时通讯,通过加解密函数和信息隐写实现安全传输、通过Vue框架实现前端交互界面、通过数据库进行用户管理等等。其中客户端和服务器端的具体功能如下:
客户端:
o 注册:与集中服务器通信完成注册,包括用户名、密码、邮箱
o 认证登陆:与集中服务器通信完成用户名、口令认证登陆
o 通信录管理功能,实现对通信录好友的添加、删除
o 即时通讯功能:实现与通信录好友间的信息发送、接收
o 透明加解密功能:采用非对称密码体制协商加密秘钥,用对称密码算法进行加解密,实现端到端的透明加解密
o 信息隐藏功能:实现以图片为载体的透明嵌入提取功能
o 人机交互界面:
服务器端:
o 用户注册:与用户通信完成注册(做必要的检验)
o 用户验证:验证用户名和密码
o 用户公钥提供:用户在发送文件时,与用户通信发送好友的公钥
o 用户在线状态维护:用户在线时记录保存用户的在线状态、IP地址和端口号
o 用户在线列表发放:负责向用户发送其好友的在线列表(包括好友用户名、IP地址、端口号)
2、可靠性要求:
- 服务器和客户端之间的通信是安全的,使用加密技术来保护数据传输。
- 系统能够防止未经授权的访问和攻击,例如拒绝服务攻击。
- 系统能够确保消息的完整性和不可否认性。
3、安全保密要求:
- 用户的注册信息,密码妥善保管,对数据库中的密码进行加盐的MD5加密处理,防止泄露,导致用户隐私泄露。
- 用户的通信内容被加密,以防止窃听。
- 系统应该使用安全的加密算法和协议,以防止被破解。
- 系统能够防止信息泄露,例如通过信息隐藏技术来隐藏敏感信息。
三、详细设计
系统结构设计
整体结构设计
采取了前后端分离式设计模式
- 前端使用HTML+CSS+JavaScript搭载了JQuery、WebSocket等技术,通过WebSocket与后端建立实时通信的连接,实现即时通讯功能。HTML负责定义页面结构,CSS负责样式美化,JavaScript负责与用户交互和动态更新页面内容。通过JQuery库,简化了DOM操作和事件处理等任务。WebSocket提供了浏览器与服务器之间的双向通信通道,实现了实时消息传输和即时更新的效果。
- 后端使用SSM(Spring+SpringMVC+MyBatis)框架技术,结合Netty等技术,以及使用Tomcat作为项目主服务器,搭建了WebSocket服务器。SSM框架提供了一种优雅简洁的方式来开发和管理后端业务逻辑,Spring提供了依赖注入和面向切面编程等特性,SpringMVC负责处理HTTP请求和路由控制,MyBatis用于数据库访问和数据持久化操作。
服务器端结构设计:
- WebSocket服务器:使用Netty框架创建一个WebSocket服务器,负责接收和处理客户端的WebSocket连接请求。
- 消息处理器:服务器端实现了消息处理器,用于处理从客户端接收到的消息,对消息进行Diffie-Hellman密钥协商分配密钥,以及使用AES加密算法对消息进行加密处理。
- 用户管理:服务器端维护了用户管理模块,管理用户的连接状态、群组归属、身份验证、在线状态等信息。
- 消息分发:服务器端需要根据用户的连接状态和目标用户来进行消息的分发,使用了订阅-发布模式,将消息发布到相应的主题(单聊、群聊),订阅了该主题的接收者会自动接收到相应的消息。
- 持久化存储:对用户信息进行持久化存储管理,通过MySQL关系型数据库对用户实体各属性进行管理。
- 用户注册合法性验证:对注册用户的邮箱进行了正则匹配,保证格式正确。
客户端结构设计:
- WebSocket客户端:使用Java提供的WebSocket客户端库,与服务器端建立WebSocket连接,发送和接收消息。
- 用户界面:客户端提供了一个用户界面,用于显示聊天消息、联系人列表等界面元素。
- 消息处理器:客户端实现了消息处理器功能,用于处理从服务器端接收到的消息,例如解析消息内容、展示消息等。
- 用户身份验证:客户端了提供用户身份验证的机制,确保只有合法用户可以连接和发送消息。
- 好友管理:客户端提供了添加好友、删除好友的接口,用于向服务器发出添加好友的POST请求。
模块设计
模块功能说明
- 注册模块(Register Module):负责用户注册功能,对用户信息进行检验,检验正确则将用户信息添加到数据库中。
- WebSocket服务器模块 :通过Netty建立起服务器,与前端WebSocket进行交互,获取连接,实现消息的发送。
- HTTP请求处理模块 :接收HTTP请求消息,通过判断消息类型,将WebSocket请求交给下一个处理器,而将其他类型的HTTP请求进行处理。
- 登录模块(Security Module) :负责用户登录功能,对登录用户信息进行合法性检测。
- 路由拦截模块(Filter Module):负责拦截用户对消息发送界面和静态资源的直接访问。
- 异常处理模块 (Exception Module) :负责捕获异常,并对异常进行打印处理。
- 单聊发送模块(Single Send Module):处理用户之间的单聊消息发送功能。接收发送方和接收方的用户ID以及消息内容,进行消息的加密和解密处理,使用Diffie-Hellman密钥交换协议进行密钥协商,生成共享秘钥,使用AES算法对消息进行加密,将加密后的消息发送给接收方。
- 群聊发送模块(Group Send Module):处理用户发送的群聊消息。接收发送方的用户ID、群组ID以及消息内容,查询群组信息,将消息发送给群组中的在线成员(除了发送方本身),实现群组内的消息广播功能。
- 移除用户模块(Remove User Module):处理用户退出聊天功能。当用户关闭连接或退出聊天时,从在线用户表中移除该用户的信息,更新在线用户数量。
- 文件单聊发送模块(File Single Send Module):处理用户之间的文件单聊发送功能。接收发送方和接收方的用户ID,文件名、大小、URL等信息,将文件相关信息发送给接收方。
- 文件群聊发送模块(File Group Send Module):处理用户发送的文件群聊消息。接收发送方的用户ID、群组ID,文件名、大小、URL等信息,查询群组信息,将文件相关信息发送给群组中的在线成员(除了发送方本身)。
- 消息类型错误模块(Type Error Module):处理消息类型错误的情况,给客户端返回错误提示信息。
- 持久层数据管理模块(MySQL Mapper Module):负责和数据库进行交互,实现对持久层数据的管理。
模块核心算法设计(要求有流程图)
消息发送模块
登录注册模块
WebSocket 连接模块
添加/删除好友模块
重要数据结构设计
1.User类
user类是我们用于管理在通讯系统中的用户的类,其定义如下:
1 | private String userId;//用户的唯一身份标识 |
针对此数据结构我们设计了针对性的数据库,其中有UserId,username,Password三个列,分别对应上文的三个同名属性。其中userId为主键。关于两个列表类,即好友列表和群组列表我们无法将其存放在一个表中,遂新建两个表来存放给群组数据以及好友数据。
2.Group类
接下来是我们的Group类,这个类我们将其用作记录小组的信息,这个类的属性比较简单,只有唯一的groupId为主键,以及groupname,groupname由groupId生成,故没有标识出来;再加上一个由user类组成的列表,作为成员列表。
1 | private String groupId; |
其中在数据库的设计方面,我们采用了第三范式的设计思路有效地降低冗余度,数据库由三个表组成;分别是:user,frineds和groups表。其中friends表只有user_Id和friend_Id两个列,userId作为主键,同时friednId和userId都被user表的userId作为外键所限制。group表同样如此,只有groupId和userId对应。
还有一个ResponseJson类,其属性较为特殊,是信息的状态,有成功和失败几种。
1 | private static final long serialVersionUID = 1L; |
程序函数清单
函数名——所在文件名
RegisterServlet,所在文件名registerservlet。
函数功能
完成用户注册功能以及用户密码加盐值
参数说明
传入的参数分别为userEmail , username以及password,都由前端传入
算法描述
我们在这里使用了try with resource来进行变量创建,这样进行查询的时候就能由java自己处理异常以及自动进行回收
singlesend-文件名chatserviceimpl
函数功能是进行聊天内容的实现,我们首先将chatservice做成了接口然后分别来进行实现。
参数说明:JSONObject param, ChannelHandlerContext ctx
分别是json的对象和一个通道处理文件,来对通道进行处理。
算法描述
我们首先进行密钥分发和加密,对在互联网上传播的信息是进行加密传输的,然后将其放入websocket中传输到待接收端。
四、系统设计难点与亮点
1、后端服务器实现即时通讯
(1)本系统的后端服务器使用Java SSM框架(Spring+SpringMVC+MyBatis)实现前后端解耦,开发独立性高,更加灵活和轻量化,与数据库的连接代码简洁;各个功能之间层次分明,便于后续对功能的增加、删除与修改,有较高的可移植性、可拓展性和可维护性。
(2)使用Netty轻量化服务器,其高并发、传输快、封装好的特性减少了socket传输过程的冗余操作;通过配置TCP-NODELAY 使得尽可能发送大块数据,减少充斥的小块数据,减少不必要的网络流量交换与延迟。
(3)开启心跳包机制,即客户端、服务端建立连接处于ESTABLISHED状态,若超过2小时没有交流,机制就会被启动,保证实时检测,实现长连接的维持和保活。
2、通过加解密与信息隐写实现的安全传输
(1)使用Diffie-Hellman密钥交换协议,通过Netty的ChannelHandleContext 传输密钥,并使用AES对称加密对内容进行加解密,实现信息的安全传输。
(2)除了传输文字消息,本系统还能进行文件、图片等多种格式内容的传输,使用户功能更加方便和多样。
(3)设计数据库时,将用户密码进行加密存储,提高用户信息安全性。
3、通过CSS,HTML,JS实现的前端人机交互界面
本系统配置了jQuery,使用websocket 实现对Netty服务器的监听和传输,并通过HTML+CSS+JavaScript实现前端的人机交互界面,美观便捷地向用户提供了操作界面。其中注册界面、登录界面和通讯系统主界面实现了自动跳转,其中注册时设置了邮箱差错检测,通讯系统界面可以实现添加删除好友功能、群聊功能、发送emoji功能、传输文件功能等多种丰富便捷的通讯功能。
五、设计成果
我们设计的安全即时通讯系统实现了以下功能:
登陆功能界面:
如果输入不正确,则弹出:
注册功能界面:
在注册中,我们也实现了检验功能,若输入不正确的信息,则显示:
通讯系统主界面:
登录成功后,原始界面显示如下,ADD与DELETE在聊天框右上角,可以通过ADD进行好友添加,DELETE进行好友删除
通讯录管理功能:添加、删除好友
设定用户的主键为邮箱,通过搜索用户邮箱进行删除,通过搜索Caicai用户的邮箱进行删除
删除Caicai好友成功:
点击ADD,添加好友,通过输入好友Caicai邮箱进行添加:
添加成功后显示用户hr已添加Caicai为好友
即时通讯功能:
添加好友后,可以开启实时通讯系统,若好友不在线,发送消息时弹出窗口进行提示,但仍可以发送信息:
点击输入框左侧的圆脸按钮,发送表情:
点击输入框左侧文件夹按钮,上传文件:
实现群组功能,登陆后可以进行群聊,666m在群里发送消息
用户hr在群里发送消息,同时可以接收到好友666m在群聊Group001中发送的消息
用户hooray可以接收到好友hr与好友666m发送的群聊消息
六、设计心得
在本次项目的程序设计中,我们对网络传输协议的混合架构、加解密和信息隐藏、实现前端界面、数据库管理等所学知识的理解更加深入,通过不断解决设计过程中的各种问题,收获了宝贵的实践经验。如在设计数据库时,具体关系如何实现、哪个是主码、需不需要外键、触发器等问题经过了许多尝试和推敲;在使用Tomcat时因版本不一致导致无法部署;由于负责后端的两位组员使用的jdk版本不一致(分别为jdk1.8、jakarta和jdk11、javax),其中jdk11的新特性导致许多地方需要修改,增大了工作量;在前后端接口设计部分遇到许多技术问题,最终通过学习和使用js中的API实现等等。在遇到问题和解决问题的过程中,我们积累了很多宝贵经验,加深了对知识的理解。
同时,我们认识到开始实现前的整体设计的重要性。由于设计初期我们对所需功能理解和认识的不全面,实现过程中不断遇到需要大量添加、修改甚至更换方法的情况,导致进展没有达到预期的速度。我们认识到团队合作中分工和沟通的重要性,在缺少合理分工和对明确目标的认识时,达到预期成果就会遇到困难。每位成员都完成自己需要负责的内容部分并及时沟通,才能更好地将设计成果整合形成一个完整的大型程序。
七、团队分工说明
王惟:服务器的开发,包括用户注册、验证、公钥提供和在线状态维护,websocket逻辑设计与实现,文档书写
夏鸿睿:客户端的开发,包括注册、认证登录、通信录管理和即时通讯功能,数据库设计与实现,文档书写
魏瑞敏 :协调团队成员工作,文档书写,完成前端登录注册聊天界面设计实现,页面调整,功能添加与接口实现
杨雅雯:客户端的端到端透明加解密功能,文档书写,聊天与通讯录设计,保密通信设计,接口实现
范茜文:查阅javaSSM框架、netty及服务器的相关资料,文档书写,登录注册聊天与系统结构逻辑设计,接口实现