文章目录
实现从文件查询账号并加密验证密码
-
idea:代码编译软件
-
Wireshark:网络封包分析软件
从文件查询用户账号并加密验证用户密码,使用Socket API编程,基于TCP的C/S程序设计,编写一个具有加密验证用户账号功能服务程序。根据提示用户输入账号字符串,客户端向服务器端发送该字符串,服务器端获得并从文件中查询该账号,该账号存在即返回一个随机数,并在服务端将该随机数与密码进行加密,客户端获得该随机数后,根据用户再次输入的密码进行和服务端同样的加密方式得到加密后字符并向服务器端发送加密后的字符,再次进行判断并向客户端返回提示;该账号不存在,则直接返回“账号不存在"。
程序时序图
详细程序流程图
加密函数
/**
* 对密码进行加密的函数
* @param plain 需要加密的字符串
* @return 返回加密后的字符串
*/
public static String MD5encrytion(String plain) {
String str = new String();
try {
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.update(plain.getBytes());
byte b[] = messageDigest.digest();
int i;
StringBuffer buf = new StringBuffer("");
for (int offset = 0; offset < b.length; offset++) {
i = b[offset];
if (i < 0) {
i += 256;
}
if (i < 26)
buf.append("0");
buf.append(Integer.toHexString(i));
}
str = buf.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return str;
}
服务端程序代码示例
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Properties;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* 思路:创建服务端
* 1、创建 SeverSocket 客户端对象
* 2、获取 Socket 流
* 3、加载文件
* 4、通过Socket,读取客户端发过来的数据
* 5、判断查询用户账号是否在config.properties文件中
* 6、存在,生成一个随机数,向客户端发送,并与该账号的密码进行加密
* 7.获得客户端返回值,与加密的字符进行比较,相同则返回"账号正确",否则返回"账号或密码不正确"
* 6、关闭Socket
*/
public class Server {
static {
System.out.println("启动成功!");
}
public static void main(String[] args) throws IOException, NoSuchAlgorithmException {
// 1、创建 SeverSocket 对象
ServerSocket ss = new ServerSocket(9999);
// 2、获取 Socket 对象
Socket s = ss.accept();
// 获取 IP 地址
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip + "连接成功!");
// 3、获取 Socket 读取流,并装饰
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
// 4、获取 Socket 的输出流,并装饰
PrintWriter out = new PrintWriter(s.getOutputStream(), true);
// 5、返回该类的Class对象(反射内容) /表示项目根目录
InputStream inputStream = Server.class.getResourceAsStream("/config.properties");
// 6、管理属性文件
Properties properties = new Properties();
properties.load(inputStream);// 从输入流中读取键值对
String line = null, str = null, result = null, pas = null;
int i = 0;
while ((line = bufIn.readLine()) != null) {
if (str == null) {
str = properties.getProperty(line);
if (str != null) {
i = (int) (Math.random() * 100);
out.println(i);
pas = str + i;
result = Server.MD5encrytion(pas);
System.out.println("服务端加密hash值:"+result);
if ((bufIn.readLine()).equals(result)) {
out.println("账号正确");
} else {
out.println("账号或密码不正确");
}
str = null;
} else {
out.println("账号不存在");
}
}
}
// 关闭资源
s.close();
ss.close();
}
}
客户端程序代码示例
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* 思路:创建客户端
* 1、创建 Socket 客户端对象
* 2、获取键盘录入的数据
* 3、将录入的信息发送给 Socket 输出流
* 4、客户端返回随机数,则输入密码,并将密码与随机数合并为一个字符串进行加密
* 5、向服务端发送加密后的字符串
* 6、读取服务端的数据并输出数据
*/
public class Client {
public static void main(String[] args) throws IOException, NoSuchAlgorithmException {
// 1、创建 Socket 客户端对象
Socket s = new Socket("127.0.0.1", 9999);
// 2、获取键盘录入
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
// 3、Socket 输出流
PrintWriter out = new PrintWriter(s.getOutputStream(), true);
// 4、Socket 输入流,读取服务端的数据
BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = null;
System.out.print("请输入要查询的用户:输入over结束)"+"\n"+"账号:");
while ((line = bufr.readLine()) != null) {
if ("over".equals(line)) {
System.out.println("客户端结束服务");
break;
}
// 输入字符串
out.println(line);
// 读取服务端返回的数据
String str = bufIn.readLine();
if (!str.equals("账号不存在")) {
System.out.println("返回随机数"+str);
System.out.print("请输入密码:");
String input = bufr.readLine();
String md = input + str;
String result = Client.MD5encrytion(md);
out.println(result);
System.out.println("客户端加密hash值:"+result);
String seresult = bufIn.readLine();
System.out.println(seresult);
}
else{
System.out.println(str);
}
System.out.print("账号:");
}
s.close();
}
}
.properties文件内容
Jim=abcde
Tom=bcde
Tony=adgc
程序调试与测试
1、启动服务器程序:
服务端启动成功,如下图所示:
图6.1 服务器程序启动成功图
2、客户端启动成功提示,
给出用户提示:
请输入要查询的用户:输入over结束)
账号:
准备接收数据,如下图所示:
3、客户端向服务端发起连接后服务端状态
127.0.0.1连接成功!
4、服务程序直接结束演示:
输入程序结束语句“over”,结果如下图所示:
5、查询正确用户账号与密码演示
向客户端输入用户账号Jim字符串,并得到服务器处理结果,如下图所示:
图5.1 客户端输入账号信息捕获图
服务端在接收到账号后,查询存在,返回一个随机数:24
图5.2 服务端返回随机数信息捕获图
服务端将通过账号查到密码,与随机数结合进行加密,并输出在服务器控制台。
图5.3 服务端随机数与文件中密码加密信息
客户端输入账号密码abcde并与服务端发送的随机数进行加密,向服务端发送加密字符。
图5.4 客户端输入密码信息捕获图
6、输入的账号不存在演示
输入账号Jimm
图6.1 客户端输入不存在的账号信息捕获图
7、输入不正确的账号密码演示
再次输入正确的账号,得到随机数:84
图7.1 客户端输入账号信息捕获图
图7.2 账号正确服务端返回随机数捕获图
服务端通过账号查到该账号的密码与随机数进行加密处理,并将加密后的字符打印在控制台。
图7.3 服务端生成加密字符图
客户端输入密码,与随机数进行加密处理,并将加密字符打印在控制台,并向服务端发送加密字符。
图7.4 客户端向服务端发送加密字符信息捕获图
8、结束输入演示
客户端输入”over”字符
图8.1 “over”客户端结束服务图
下载资源代码:WenhuaProject.zip