So, I am currently learning SpringBoot and right now I am trying to store a password together with other data for the users in a database (MySql). In order for it to be secure I am using salted hashes to store. Generating these hashes and storing them in the database works fine, however when I try to validate the password by taking the salt and the password, I am getting a different hash, therefore the wrong result.
Below is my code.
First of: The class User
where I start the validation
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private long uID;
@NotNull
private String nname;
@NotNull
private String vname;
private String email;
private String telnr;
@Embedded
private Address address;
@NotNull
private boolean isAdmin;
private String hash;
// Default Constructor
public User() {
}
// Constructor
public User(String name, String vname, String email, String telnr, Address address, boolean isAdmin,
String password) throws NoSuchAlgorithmException {
HashHelper hashHelper = new HashHelper();
this.nname = name;
this.vname = vname;
this.email = email;
this.telnr = telnr;
this.address = address;
this.isAdmin = isAdmin;
this.hash = hashHelper.createHash(password);
}
public boolean validateHash(String password) {
HashHelper hashHelper = new HashHelper();
// Get the used Salt
String[] parts = this.hash.split(":");
byte[] salt = parts[0].getBytes();
// Create Hash with old salt
String newHash = hashHelper.getHash(password, salt);
if (parts[1] == newHash) {
return true;
}
return false;
}
Second, my class HashHelper
where I handle everything to do with hashing. I use createHash
whenever a new password gets stored (therefore, new salt) and getHash
for validation with a specific salt.
public class HashHelper {
public HashHelper() {
}
public byte[] getSalt() throws NoSuchAlgorithmException {
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
byte[] salt = new byte[16];
sr.nextBytes(salt);
return salt;
}
// Create Salt and Hash and store them, seperated by :
public String createHash(String password) throws NoSuchAlgorithmException {
String hash = null;
byte[] salts = getSalt();
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(salts);
byte[] bytes = md.digest(password.getBytes());
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
}
hash=salts.toString() + ":" + sb.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
System.out.println("Hash: " + hash);
return hash;
}
public String getHash(String password, byte[] salt) {
String hash = "";
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(salt);
byte[] bytes = md.digest(password.getBytes());
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
}
hash = sb.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return hash;
}
}
The call for validation is set in a CommandLineRunner just for testing and is the following:
Optional<User> user = userRepository.findById((long)10);
if (user.get().validateHash("Password")) {
System.out.println("Correct Password");
}
else {
System.out.println("Wrong password");
}
I think it was something to do with the getBytes()
and toString()
methods, because byte[] salt
seems to have a shorter length when I try to validate it (around 11-12 bytes instead of 16) but I can't figure out why. Any help would be greatly appreciated!