前言
本文介绍的是基于Kerberos认证协议的学生成绩管理系统,主要实现的是Kerberos认证协议部分,学生成绩管理部分通过网页实现。
一、软件介绍
1.软件名称
基于Kerberos认证协议的学生成绩管理系统。
2.软件功能模块划分
- 用户管理模块(包括教师和学生);
- 权限验证模块;
- 成绩管理模块;
- 用户数据的认证追溯和高度保密性;
- 基于kerberos协议实现信息的安全传输;
- 分布式应用服务器的高并发处理。
3.开发环境
运行环境:Windows10
开发环境:
IntelliJ IDEA 2021
mysql 5.7
Navicat for Mysql
Maven 3.6.1
JDK 1.8
开发语言:Java
开发框架:springboot+Mybaties+layui
二、需求分析
1.用户需求分析
此系统共有两类用户,分别是教师和学生。
其中,教师拥有以下权限:
查看所有学生成绩,添加学生相关信息、修改学生信息和删除学生信息。
学生只能查看自己的成绩。
2.功能需求分析
- 用户管理模块(包括教师和学生)
为保证系统的安全性,教师和学生分别用其账号和密码进行登录。 - 权限验证模块
教师和学生拥有不同的账号和密码,登录时系统自动甄别登录者身份,进入不同的模块,且学生只能查看自己的信息,无法获取他人的信息。 - 成绩管理模块
成绩分为习题成绩、测验成绩、考试成绩。
教师:
查看、添加、修改、删除、搜索学生信息,其中学号不能被修改。
查看、添加、修改、删除、统计学生成绩,可通过搜索学生姓名查看学生的相关成绩。
学生:
查看自己的各类成绩和总成绩。 - 用户数据的认证追溯和高度保密性
用户数据在数据库和传输过程均为加密存储和传输,并且使用数字签名,保证系统的安全性。 - 基于kerberos协议实现信息的安全传输
当客户端请求各类服务时,均使用使用kerberos协议认证方式,以保证系统信息的安全传输。 - 分布式应用服务器的高并发处理
使用多线程方式实现系统的并发处理。
3.功能模块图
三、整体框架设计
1.功能
-
客户端kerberos
通过向各个端进行认证来保证系统的安全性。 -
服务端
向AS、TGS、服务端发送请求,与用户进行交互,完成用户登录、上传成绩、修改成绩、查询成绩、统计、排序、删除成绩等功能。 -
AS、TGS
进行安全认证。
四、详细设计
1.连接数据库
使用springboot项目中自带的application.properties文件中进行数据库的相关配置,定义端口号:
代码如下:
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.platform=mysql
spring.datasource.url=jdbc:mysql://localhost:3306/score?characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
mybatis.typeAliasesPackage=com.score.bean
mybatis.mapperLocations=classpath:mapper/*.xml
server.port=8088
2.多线程通信
客户端和AS、TGS模块之间通过多线程socket方式通信,以保证分布式应用服务器的高并发处理,目前可以保证小组三人同时进入系统,且等待时间较短。
代码如下
以客户端向AS端发送请求为例::
try {
String send_username = String.valueOf(student.getStudentNo());//获取用户账号
//String send_password=user.getPassword();//获取用户密码
String send_notime = get_nowtime();//获取当前时间
String send_idtgs = "abcd";
Socket socket = new Socket("192.168.43.254", 10068);//AS目标主机ip地址和端口号
OutputStream outputStream = socket.getOutputStream();//得到一个输出流,用于向服务器发送数据
OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8");//将写入的字符编码成字节后写入一个字节流
String data = dig_str + send_username + send_idtgs + send_notime;//向AS端传输数字签名、用户名、TGS ID,用户名,时间戳
writer.write(data);//发送数据签名和登录数据
sl.add("学生端C给AS报文"+data);
writer.flush();//刷新缓冲
socket.shutdownOutput();//只关闭输出流而不关闭连接
InputStream inputStream = socket.getInputStream();//得到一个输入流,用于接收服务器响应的数据
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");//将一个字节流中的字节解码成字符
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);//为输入流添加缓冲
String info = null;
get_message2 = new String();
System.out.println("客户端IP地址:" + socket.getInetAddress().getHostAddress());//输出服务器端响应数据
while ((info = bufferedReader.readLine()) != null) {
//System.out.println("客户端接收:" + info);
get_message2 = info;//将AS端的报文提取出来
}
get_message = get_message2.substring(1, 557);//截取报文
System.out.println("cilent从AS端获取的报文为" + get_message);//接收到的加密报文
String message_open = DES.DecryptDES(get_message, Ek_c);//DES解密报文
System.out.println("解密后的报文为" + message_open);//输出解密后的报文
get_TGT = message_open.substring(219, 411);//报文中截取TGT
System.out.println("TGT报文为" + get_TGT);
String get_Kctgs1 = message_open.substring(0, 172);
System.out.println("加密后的Kc_tgs为" + get_Kctgs1);
String publicKey = new String(org.apache.commons.codec.binary.Base64.encodeBase64(keyPair.getPublic().getEncoded()));
String privateKey = new String(org.apache.commons.codec.binary.Base64.encodeBase64(keyPair.getPrivate().getEncoded()));*/
get_Kctgs = RSA.decrypt(get_Kctgs1, RSA.getPrivateKey(privateKey));//客户端解密Kctgs
//关闭资源
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
writer.close();
outputStream.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
throw new RuntimeException(e);
}
客户端与TGS的通信流程代码和与AS端通信部分大致相同,因此不再赘述。
3.Kerberos认证模块
1.客户端与AS:
以登录为例进行介绍
- 客户端向AS发送请求:
Message1: 客户端需要登录用户IDc封装的数字签名 + 客户端需要登录用户IDc + tgs的ip地址IDtgs + AS端的时间TS1
将Message1发送给AS。
- 客户端接收AS回复的消息:
K_c,tgs:
由AS产生,用于AS与client之间信息的安全交换,并且会定期更换,用RSA的密钥,即客户端的公钥加密。
Ticket_tgs: 用des的密钥E_K_tgs 加密以下信息:
RSA加密后的 K_c,tgs + 客户端需要登录的用户名TDc + AS端记录的用户名ADc + TGS的ip地址IDtgs + AS端的时间戳TS2 + 存活时间Lifetime2。
Message2: 用des的密钥E_K_c 加密以下信息:
加密后的K_c,tgs + TGS的ip地址IDtgs + AS端的时间戳TS2 + 存活时间Lifetime2 + Ticket_tgs
此时客户端拥有的密钥有:E_K_c 、K_c,tgs、RSA私钥。
客户端解密消息得到:
K_c,tgs、IDtgs、TS2、Lifetime2、Ticket_tgs
客户端无法解密Ticket_tgs,因此将其发送给TGS。
2.客户端与TGS:
- 客户端向TGS发送请求:
Authenticator_c:用客户端和TGS共享的DES密钥E_(K_(c,tgs) )加密以下信息:
IDc + AS中存放的客户端需登录用户名ADc + 客户端时间戳TS3
Message3:客户端要访问的服务器地址IDv + Ticket_tgs + Authenticator_c
- 客户端接收TGS回复的消息:
Message4: 用E_(K_(c,tgs) )加密以下消息:
用RSA公钥加密的K_(c,v) + IDv + TGS端时间戳TS4 + Ticket_v
Ticket_v:用V的密钥E_(K_v )加密以下信息:
K_(c,v) + IDc + ADc + IDv + TS4 + Lifetime4
客户端用其和TGS共享的DES密钥E_(K_(c,tgs) )解密Message4,得到:
K_(c,v) + IDv + TGS端时间戳TS4 + 无法解密的 Ticket_v
此时客户端拥有的密钥有:
E_(K_c ) 、K_(c,tgs)、RSA私钥、K_(c,v)、E_(K_(c,tgs) )
因客户端无法加密,会将 Ticket_v 发送给V进行解密。
3.客户端与V:
- 客户端向V发送请求:
Authenticator_c:用客户端和V共享的DES密钥E_(K_(c,v) )加密以下信息:
IDc + ADc + 客户端时间戳TS5
Message5: Ticket_v + Authenticator_c
- 客户端接收V回复的消息:
Message6: 用E_(K_(c,v) )加密以下消息:
TS5+1
接着用户在客户端输入用户密码进行身份认证。
4.信息安全传输
1.服务端和客户端
客户端向服务端发送数据时,都会将数据用AES加密后再进行传输,服务端收到客户端的报文后只对报文中请求部分进行解密,不会对用户的任何数据进行解密,直接将数据传至数据库或和数据库中的数据进行比较。
服务端向客户端发送的数据也通过AES进行加密,当数据到达客户端后,客户端自行解密并展示。
2.服务端和数据库
数据库中事先存储用户的信息,并事先把除主键外用户的所有数据使用AES进行加密,便可实现服务端在数据库中查找、添加、修改等功能了。
总结
因时间原因,暂时就写到这啦,因为是第一次接触spring boot,不太熟悉,项目会存在一些问题,今后会持续更新,欢迎批评指正。