具有质询-响应的认证系统
Posted
技术标签:
【中文标题】具有质询-响应的认证系统【英文标题】:Authentication System with Challenge-Response 【发布时间】:2022-01-21 13:24:43 【问题描述】:我对 Java 很陌生,对编程也很陌生。我的任务是建立一个至少有两个用户和一个挑战-响应-请求的身份验证系统。 我使用 MD5 和 Salt 生成了密码哈希,我只是找不到一种方法来询问客户端输入的密码是否等于生成的密码哈希。我也不知道如何告诉我的客户盐是什么。
这是我目前构建的。
Server
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
public class server
ServerSocket serversocket;
Socket client;
BufferedReader input;
PrintWriter output;
public void start() throws IOException
serversocket = new ServerSocket(9090);
System.out.println("Connection Starting on port:" + serversocket.getLocalPort() );
//make connection to client on port specified
//accept connection from client
client = serversocket.accept();
System.out.println("Waiting for connection from client");
try
logInfo();
catch (Exception e)
// TODO Auto-generated catch block
e.printStackTrace();
public static void main1(String[] args) throws Exception
String pass1 = "karotte";
String pass2 = "tomate";
String algorithm = "MD5";
byte[] salt = createSalt();
System.out.println("Bob MD5 Hash: "+ generateHash1(pass1, algorithm, salt));
System.out.println("Alice MD5 Hash: "+ generateHash2(pass2, algorithm, salt));
private static
String generateHash1(String pass1, String algorithm, byte[] salt) throws NoSuchAlgorithmException
MessageDigest digest = MessageDigest.getInstance(algorithm);
digest.reset();
digest.update(salt);
byte[] hash = digest.digest(pass1.getBytes());
return bytesToStringHex(hash);
static String generateHash2(String pass2, String algorithm, byte[] salt) throws NoSuchAlgorithmException
MessageDigest digest = MessageDigest.getInstance(algorithm);
digest.reset();
digest.update(salt);
byte[] hash = digest.digest(pass2.getBytes());
return bytesToStringHex(hash);
private final static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToStringHex(byte[] bytes)
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++)
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
return new String(hexChars);
public static byte[] createSalt()
byte[] bytes = new byte[5];
SecureRandom random = new SecureRandom();
random.nextBytes(bytes);
return bytes;
public void logInfo() throws Exception
//open buffered reader for reading data from client
input = new BufferedReader(new InputStreamReader(client.getInputStream()));
String username = input.readLine();
System.out.println("username" + username);
String password = input.readLine();
System.out.println("password" + password);
//open printwriter for writing data to client
output = new PrintWriter(new OutputStreamWriter(client.getOutputStream()));
if(username.equals("Bob") &&password.equals())
output.println("Welcome, " + username);
else
if
(username.equals("Alice) &&password.equals())
output.println("Welcome, "+ username);
else
output.println("Login Failed");
output.flush();
output.close();
public static void main(String[] args)
server server = new server();
try
server.start();
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
Client
import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JOptionPane;
public class client
Socket socket;
BufferedReader read;
PrintWriter output;
public void startClient() throws UnknownHostException, IOException
//Create socket connection
socket = new Socket("localhost", 9090);
//create printwriter for sending login to server
output = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
//prompt for user name
String username = JOptionPane.showInputDialog(null, "Enter User Name:");
//send user name to server
output.println(username);
//prompt for password
String password = JOptionPane.showInputDialog(null, "Enter Password");
//send password to server
output.println(password);
output.flush();
//create Buffered reader for reading response from server
read = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//read response from server
String response = read.readLine();
System.out.println("This is the response: " + response);
//display response
JOptionPane.showMessageDialog(null, response);
public static void main(String args[])
client client = new client();
try
client.startClient();
catch (UnknownHostException e)
// TODO Auto-generated catch block
e.printStackTrace();
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
```
【问题讨论】:
为什么客户需要知道盐是什么? 因为响应是 Hash = (challenge + password)。那么盐不是挑战吗? 【参考方案1】:如果您是关于客户端/服务器连接,为什么不使用基于 SSl 和 X509 证书的相互身份验证? 它易于设置并增加了额外的安全性。
【讨论】:
以上是关于具有质询-响应的认证系统的主要内容,如果未能解决你的问题,请参考以下文章