I'm making a basic user authentication system on console in java. The user enters their username and password and I store the encrypted password with SHA-512 in a file. Then I prompt the user to "log in" and i need to validate that the password they input this time is the password they entered when they "signed up". The problem arises in the validation part. When i store the password, I store the salt along with it in the file. But because the salt is a byte[]
array, it shows the same [B@232204a1
when i convert it to a string and store it in the file.
Through this answer what i did was that i stored the salt byte array values in a string by concatenating them together so it'd be a continuous value and easier to read during validation.
In the validation part, i read the stored salt correctly, but when i use .getBytes()
and then use the same code from the link above, it ouputs a different value than the one i had stored. And hence when i use it to calculate the hashed password, it obviously gives me the wrong answer.
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;
}
}
Now I understand that I'm going wrong in the conversion of byte to string and back but I have no other idea of how to make this work with a file. I'd really appreciate it if someone could help me.