Итак, я сейчас изучаю SpringBoot и сейчас пытаюсь сохранить пароль вместе с другими данными для пользователей в базе данных (MySql).Для того, чтобы это было безопасно, я использую соленые хэши для хранения.Генерация этих хешей и сохранение их в базе данных работает нормально, однако, когда я пытаюсь подтвердить пароль, взяв соль и пароль, я получаю другой хеш, поэтому неверный результат.
Ниже приведен мой код.
Во-первых: класс User
, где я начинаю проверку
@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;
}
Во-вторых, мой класс HashHelper
, где я обрабатываю все, что связано с хэшированием.Я использую createHash
всякий раз, когда сохраняется новый пароль (следовательно, новая соль) и getHash
для проверки с помощью конкретной соли.
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;
}
}
Вызов для проверки устанавливается в CommandLineRunner только для тестирования ивыглядит следующим образом:
Optional<User> user = userRepository.findById((long)10);
if (user.get().validateHash("Password")) {
System.out.println("Correct Password");
}
else {
System.out.println("Wrong password");
}
Я думаю, что это было связано с методами getBytes()
и toString()
, потому что byte[] salt
имеет меньшую длину, когда я пытаюсь его проверить (около 11-12 байт вместо 16) но я не могу понять, почему.Любая помощь будет принята с благодарностью!