Хешировать в базу данных

Я сейчас работаю над своим маленьким проектом, и у меня есть вопрос, потому что я не могу его понять. В основном я использую netbeans и создаю логин / регистрацию с проверкой и сохраняю данные в базе данных, я пытаюсь реализовать функцию хеширования, пока кто-то регистрируется, чтобы текст не сохранялся как простой текст в базе данных.

Я пробовал несколько руководств по внедрению хеширования в свой проект, но не могу этого сделать. Любые подсказки приветствуются.

Это форма регистрации:

    String name = this.name.getText();
    String lastname = this.lastname.getText();
    String email = this.email.getText();
    String pass = new String(password.getPassword());
    String repass = this.repassword.getText();

    boolean valid = true;
    // Declaraction on name                  
    if (name.length() > 15 || name.length() < 3){
        JOptionPane.showMessageDialog(null, "Please enter your correct name", "Incorrect details", JOptionPane.ERROR_MESSAGE);
        valid = false;
    }
    if (name.equals("")){
        JOptionPane.showMessageDialog(null, "Name can't be empty", "Incorrect details", JOptionPane.ERROR_MESSAGE);
        valid = false;
    }
    //Declaraction on surname
    if (lastname.length() > 20 || lastname.length() < 3){
        JOptionPane.showMessageDialog(null, "Please enter your correct surname", "Incorrect details", JOptionPane.ERROR_MESSAGE);
        valid = false;
    }
    if (lastname.equals("")){
        JOptionPane.showMessageDialog(null, "Surname can't be empty", "Incorrect details", JOptionPane.ERROR_MESSAGE);
        valid = false;
    }
    //Declaraction of email
    if (!(Pattern.matches("^[a-zA-Z0-9-_]+[@]+[gmail]+[.]+[com]+$", this.email.getText()))){
        JOptionPane.showMessageDialog(null, "Please enter a Gmail email", "Incorrect details", JOptionPane.ERROR_MESSAGE);
        valid = false;
    }
    //Declaraction of password / repeat password
    if (pass.length() > 15 || pass.length() < 8){
        JOptionPane.showMessageDialog(null, "Password should be less than 15 and more than 8 characters in length.", "Incorrect details", JOptionPane.ERROR_MESSAGE);
        valid = false;
    }
    if (pass.contains(name)){
        JOptionPane.showMessageDialog(null, "Password Should not contain same words as your name", "Incorrect details", JOptionPane.ERROR_MESSAGE);
        valid = false;
    }
    String upperCaseChars = "(.*[A-Z].*)";
    if (!pass.matches(upperCaseChars )){
        JOptionPane.showMessageDialog(null, "Password should contain atleast one upper case alphabet", "Incorrect details", JOptionPane.ERROR_MESSAGE);
        valid = false;
    }
    String lowerCaseChars = "(.*[a-z].*)";
    if (!pass.matches(lowerCaseChars )){
        JOptionPane.showMessageDialog(null, "Password should contain atleast one lower case alphabet", "Incorrect details", JOptionPane.ERROR_MESSAGE);
        valid = false;
    }
    String numbers = "(.*[0-9].*)";
    if (!pass.matches(numbers )){
        JOptionPane.showMessageDialog(null, "Password should contain atleast one number.", "Incorrect details", JOptionPane.ERROR_MESSAGE);
        valid = false;
    }
    if (!pass.matches(repass)){
        JOptionPane.showMessageDialog(null, "Passwords dont match.", "Incorrect details", JOptionPane.ERROR_MESSAGE);
        valid = false;
    }
    if (valid){
        User u = new User();
        u.setID(0);
        u.setName(name);
        u.setLastname(lastname);
        u.setEmail(email);
        u.setPassword(pass);
        u.setRepassword(repass);

        UserController uc = new UserController();

        int res = uc.createAccount(u);

        if (res > 0) {
            JOptionPane.showMessageDialog(null, "You have been Registered");

        }
        else {
            JOptionPane.showMessageDialog(null, "Unable to Register", "Incorrect details", JOptionPane.ERROR_MESSAGE);
        }
    }

Все это происходит после того, как пользователь нажимает кнопку «зарегистрироваться» в графическом интерфейсе.

Мой полный UserController, который сохраняет в базу данных + извлекает, находится здесь:

public class UserController extends User{    
Database db;
Connection con;
PreparedStatement pst;

public UserController() {
    super();
    db = new Database();
    con = db.getConnection();
}

public int createAccount(User u) {
    int res = 0;
    String sql = "";

    try {
        sql = "INSERT INTO user(`id`,`name`,`lastname`,`email`,`password`,`repassword`) VALUES(NULL, ?, ?, ?, ?, ?)";
        pst = con.prepareStatement(sql);

        pst.setString(1, u.getName());
        pst.setString(2, u.getLastname());
        pst.setString(3, u.getEmail());
        pst.setString(4, u.getPassword());
        pst.setString(5, u.getRepassword());

        res = pst.executeUpdate();

    } catch (SQLException e) {
        System.out.println(e.getMessage());
    }

    return res;
}    
private String md5(char[] c){
    try{
    MessageDigest digs = MessageDigest.getInstance("MD5");

    digs.update(new String(c).getBytes("UTF8"));
    String str = new String(digs.digest());
    return str;        
    }
    catch(Exception ex){
        return "";
    }
}

public boolean checkLogin(User u) {

    String sql = "";
    ResultSet rs = null;

    try {
        sql = "SELECT * FROM user WHERE email = ? and password = ?";
        pst = con.prepareStatement(sql);

        pst.setString(1, u.getEmail());
        pst.setString(2, u.getPassword());

        rs = pst.executeQuery();

        if (rs.next()) {
            return true;
        } else {
            return false;
        }


    } catch(SQLException e) {
        System.out.println(e.getMessage());
    }


    return false;


 }
}

Любые намеки на то, должен ли я его реализовать, или любые намеки на то, как это сделать, будут оценены, просто повторюсь, я использую netbeans для разработки. Спасибо всем.

При сохранении верификатора пароля простого использования хеш-функции недостаточно, и простое добавление соли мало способствует повышению безопасности. Вместо этого перебирайте HMAC со случайной солью в течение примерно 100 мс и сохраняйте соль с хешем. Еще лучше использовать такие функции, как PBKDF2, Rfc2898DeriveBytes, Argon2, password_hash, Bcrypt или аналогичные функции. Смысл в том, чтобы заставить злоумышленника тратить много времени на поиск паролей с помощью грубой силы.

zaph 08.04.2018 15:56
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
1
95
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать этот метод для хеширования пароля перед его сохранением в базе данных.

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;


public class PasswordUtils {



 private final static String SALT = "your_salt_string_here";


  /**
   * Hash a password with SHA-1 algorithm and salt.
   * 
   * @param password  The password to encrypt.
   * @return            The hexadecimal number representation of the encrypted password.
   */
  public static String hashPassword(String password) {
    String result = null;
    MessageDigest md;

    try {
        md = MessageDigest.getInstance("SHA-1");
        byte[] hash1 = md.digest(password.getBytes());

        md.reset();
        byte[] hash2 = md.digest(hash1);

        md.reset();
        md.update(SALT.getBytes());
        md.update(hash2);

        byte[] digest = md.digest();
        for (int i = 0; i < digest.length; i++) {
            digest[i] = (byte) (digest[i] ^ hash1[i]);
        }   

        result = String.format("%0" + (digest.length << 1) + "x",new BigInteger(1,digest));     

    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }

    return result;
  }
}

спасибо за ваш ответ, где я могу это реализовать? В кнопку или в мой UserController?

Dawid Trojanowski 08.04.2018 13:24

Поместите его в новый класс и используйте там, где вам это нужно.

jonhid 08.04.2018 13:27

Спасибо, работает отлично! Ты спас мне день; Я сижу на этом со вчерашнего дня и не мог понять. Спасибо !

Dawid Trojanowski 08.04.2018 13:33

SHA1, все методы криптографического хеширования, не являются шифрованием. Хеш-функции односторонние, то есть нет возможности восстановить исходный ввод. Шифрование слишком сложное, ввод можно восстановить с помощью ключа, который использовался для шифрования.

zaph 08.04.2018 15:56

Этот метод пароля небезопасен, не использовать. Кроме того, это просто неправильное перемешивание или хеширование, вместо этого используйте хорошо проверенный метод, такой как PBKDF2, Rfc2898DeriveBytes, Argon2, password_hash, Bcrypt или аналогичные функции. «Закон Шнайера»: «Любой человек, от самого невежественного любителя до лучшего криптографа, может создать алгоритм, который он сам не сможет сломать.»

zaph 08.04.2018 15:59

Другие вопросы по теме