我正在用java在控制台上制作一个基本的用户身份验证系统。用户输入用户名和密码,我用sha-512将加密密码存储在一个文件中。然后我提示用户“登录”,我需要验证他们这次输入的密码是他们“注册”时输入的密码。问题出现在验证部分。当我存储密码时,我会将盐和它一起存储在文件中。但因为盐是 byte[]
数组,它显示相同的 [B@232204a1
当我将它转换为字符串并存储在文件中时。
通过这个答案,我将salt字节数组值存储在一个字符串中,方法是将它们串联在一起,这样它就可以是一个连续的值,并且在验证期间更容易读取。
在验证部分,我正确地读取了存储的盐,但是当我使用 .getBytes()
然后使用上面链接中的相同代码,它输出的值与我存储的值不同。因此,当我用它来计算散列密码时,它显然给出了错误的答案。
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Scanner;
public class authenticationSystem {
private byte[] salt;
public static void main(String[] args) throws NoSuchAlgorithmException
{
Scanner sc = new Scanner(System.in);
byte[] salt = getSalt();
System.out.println("Enter 1 for Sign up and 2 for log in and -1 to exit");
int option = Integer.parseInt(sc.nextLine());
switch(option) {
case 1:
System.out.println("Enter Username: ");
String username = sc.nextLine();
System.out.println("Enter Password: ");
String passwordToHash = sc.nextLine();
boolean signupResult = signUp(username, passwordToHash, salt);
if(signupResult == false) {
System.exit(0);
}
else {
System.out.println("SignUp Successful");
break;
}
case 2:
System.out.println("Enter Username: ");
username = sc.nextLine();
System.out.println("Enter Password: ");
passwordToHash = sc.nextLine();
boolean loginResult = logIn(username, passwordToHash);
if(loginResult == false) {
System.out.println("Authentication Failed!");
break;
}
else {
System.out.println("Authentication Successful!");
break;
}
}
}
private static boolean logIn(String username, String password) {
String absolutePath = "C:\\Users\\asadn\\eclipse-workspace\\output.txt";
File file = new File(absolutePath);
try(BufferedReader bufferedReader = new BufferedReader(new FileReader(absolutePath))) {
String currentLine = null;
int count=1;
while((currentLine = bufferedReader.readLine()) != null) {
if(currentLine.equals(username)) {
currentLine = bufferedReader.readLine(); //get to line with salt
System.out.println(currentLine);
byte[] salt = currentLine.getBytes();
System.out.println(salt);
for(int i = 0; i<salt.length; i++) {
System.out.print(salt[i] & 0x00FF);
System.out.print("");
}
System.out.println("");
currentLine = bufferedReader.readLine(); //get to line with hashedPassword
String passwordToMatch = currentLine; //store in a string variable for comparison
System.out.println(passwordToMatch);
String passwordRetrieved = get_SHA_512_SecurePassword(password, salt);
System.out.println(passwordRetrieved);
if(passwordToMatch.equals(passwordRetrieved)){
return true;
}
}
}
} catch (FileNotFoundException e) {
// exception handling
} catch (IOException e) {
// exception handling
}
return false;
}
private static boolean signUp(String username, String hashedPassword, byte[] salt) {
String absolutePath = "C:\\Users\\asadn\\eclipse-workspace\\output.txt";
File file = new File(absolutePath);
String saltInStringFormat = "";
for(int i = 0; i<salt.length; i++) {
saltInStringFormat+=Integer.toString(salt[i] & 0x00FF);
}
// write the content in file
try(BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file, true))) {
String securePassword = get_SHA_512_SecurePassword(hashedPassword, salt);
bufferedWriter.write(username);
bufferedWriter.newLine();
bufferedWriter.write(saltInStringFormat);
bufferedWriter.newLine();
bufferedWriter.write(securePassword);
bufferedWriter.newLine();
bufferedWriter.close();
} catch (IOException e) {
// exception handling
return false;
}
return true;
}
private static String get_SHA_512_SecurePassword(String passwordToHash, byte[] salt)
{
//Use MessageDigest md = MessageDigest.getInstance("SHA-512");
String generatedPassword = null;
try {
MessageDigest md = MessageDigest.getInstance("SHA-512");
md.update(salt);
byte[] bytes = md.digest(passwordToHash.getBytes());
StringBuilder sb = new StringBuilder();
for(int i=0; i< bytes.length ;i++)
{
sb.append(Integer.toString((bytes[i] & 0xff + 0x100), 16).substring(1));
}
generatedPassword = sb.toString();
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
return generatedPassword;
}
//Add salt
private static byte[] getSalt() throws NoSuchAlgorithmException
{
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
byte[] salt = new byte[16];
sr.nextBytes(salt);
return salt;
}
}
现在我知道我在字节到字符串的转换和反转换中出错了,但是我不知道如何在文件中实现这一点。如果有人能帮我,我会非常感激的。
暂无答案!
目前还没有任何答案,快来回答吧!