Хэш в базу данных

avatar
Dawid Trojanowski
8 апреля 2018 в 11:13
150
1
-1

Сейчас я работаю над своим маленьким проектом, и у меня есть вопрос, потому что я не могу его понять. В основном я использую 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 для разработки. Всем спасибо.

Источник
zaph
8 апреля 2018 в 13:56
0

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

Ответы (1)

avatar
jonhid
8 апреля 2018 в 11:20
0

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

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;
  }
}
Dawid Trojanowski
8 апреля 2018 в 11:24
0

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

jonhid
8 апреля 2018 в 11:27
1

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

Dawid Trojanowski
8 апреля 2018 в 11:33
0

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

zaph
8 апреля 2018 в 13:56
0

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

zaph
8 апреля 2018 в 13:59
0

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