Использование Jasypt: метод checkPassword возвращает false, когда пароли должны совпадать.

Чтобы дать вам некоторую информацию, моя команда и я создаем программу, которая хранит имена пользователей и пароли в базе данных. Мы используем Java и взаимодействуем с базой данных через код Java.

Мы используем Jasypt для шифрования имен пользователей и паролей. Я использую BasicPasswordEncryptor в Jasypt для шифрования обоих. Имена пользователей отлично шифруются и прекрасно сохраняются в базе данных. Однако, когда логин проверяется и указанный BasicPasswordEncryptor пытается сравнить имя пользователя в открытом виде с зашифрованным паролем, он всегда возвращает false. Я сделал серию проверок, чтобы сосредоточиться на том, где возникает проблема. Насколько я знаю, это проблема с Jasypt. Кто-нибудь знает, в чем проблема, возможное решение или более оптимальный метод? Спасибо. Я опубликую код.

Здесь происходит шифрование.

public void register(String userName, String passWord){
    String encryptedUsername = e.encryptPassword(userName);
    String encryptedPassword = e.encryptPassword(passWord);
    System.out.println("Registered eU: " + encryptedUsername);
    try {
        con = DriverManager.getConnection("jdbc:mysql://localhost:3306/PandaBox", "root", "");
        statement = con.prepareStatement("insert into Users (username, password, logged) values (?,?,?)");
        statement.setString(1, encryptedUsername);
        statement.setString(2, encryptedPassword);
        statement.setInt(3, 0);
        boolean x = statement.execute();
        System.out.println("IT REGISTERED");

    } catch (SQLException o) {
        o.printStackTrace();
    }
}

Где «e» — это объект BasicPasswordEncryptor. Вот проверка входа.

public boolean checkLogin(String inputedUsername, String inputedPassword) {
    try {
        con = DriverManager.getConnection("jdbc:mysql://localhost:3306/PandaBox", "root", "");
        statement = con.prepareStatement("select * from Users");
        rs = statement.executeQuery();
        System.out.println(inputedUsername + " / " + inputedPassword);

        while(rs.next()){
            String usernameInDatabase = rs.getString("username");
            System.out.println(usernameInDatabase);
            if (e.checkPassword(inputedUsername, usernameInDatabase)) {  
                System.out.println("Username correct.");
                statement = con.prepareStatement("select password from Users where username = ?");
                statement.setString(1, usernameInDatabase);
                rs = statement.executeQuery();
                String passwordInDatabase = rs.toString();
                if(passwordIsCorrect(inputedPassword, passwordInDatabase)){
                    return true;
                }                                               
            }                                   
        }
        return false;
    } catch (SQLException o) {
        // TODO Auto-generated catch block
        o.printStackTrace();
        return false;
    }

}

person dysruption    schedule 10.01.2012    source источник


Ответы (2)


Я автор jasypt.

Из вашего сообщения мне не ясно, наблюдаете ли вы эту проблему при сопоставлении имени пользователя или пароля — вы говорите «попытки сверить имя пользователя в виде открытого текста с зашифрованным паролем», что не имеет смысла —. Тем не менее, одна из наиболее распространенных причин таких проблем, как ваша, заключается в том, что столбцы вашей базы данных недостаточно велики для хранения ваших хешированных имен пользователей и/или паролей.

Размер результата хеширования будет зависеть от используемого алгоритма и конфигурации соли, но для BasicPasswordEncryptor, который использует MD5 и размер соли 8 байт, вы должны ожидать, что ваши хэши будут 16-байтовыми (хэш) плюс 8 байтов ( соль), плюс 8 дополнительных байтов из-за текстовой кодировки Base64. Всего 32 байта.

Также подумайте, что многие СУБД измеряют поля varchar в символах, а не в байтах, поэтому вам следует выполнить соответствующее преобразование в зависимости от кодировки символов, используемой в вашей таблице.

Я всегда рекомендую сначала проверять размеры столбцов, потому что многие СУБД не выдают ошибку, если вы пытаетесь сохранить слишком длинный для столбца varchar — они просто обрезают его. Я не знаю поведения MySQL, но Oracle делает именно это. И когда вы пытаетесь расшифровать его обратно... он не совпадает.

Поэтому проверка размеров столбцов может стать хорошей отправной точкой. И помните, что у jasypt есть пользовательский форум по адресу http://forum.jasypt.org.

Да, и, кстати, простите меня, если это просто демонстрационный код ad-hoc, но на всякий случай: вы должны убедиться, что закрыли все свои объекты Statement и ResultSet в блоках «finally» перед их повторным использованием... так что вы следует использовать разные переменные «оператор» и «rs» во внутреннем блоке итераций и каждый раз закрывать их.

С Уважением.

person Daniel Fernández    schedule 11.01.2012

Оптимизация 1: используйте предложение WHERE.

person Mark Green    schedule 10.01.2012
comment
Этот пользователь не может использовать предложение WHERE в 'select * from Users', потому что он/она использует BasicPasswordEncryptor, который из-за использования случайной соли выводит разные, но все действительные, результаты каждый раз, когда вызывается 'encryptPassword'. Так что, учитывая тот факт, что он/она также использует этот шифратор для хеширования имени пользователя, нет никакого способа создать значение, позволяющее использовать оператор равенства в предложении WHERE. Единственный способ — перебрать их все и проверить каждую отдельно, как это делает этот пользователь. - person Daniel Fernández; 11.01.2012
comment
Таким образом, он не должен шифровать пользователей с помощью случайного генератора соли. - person sfratini; 12.04.2012
comment
Как мы можем проверить, является ли значение, присутствующее в базе данных, хешированным или не использующим B crypt? Спасибо, Неха - person Pra_A; 29.09.2015
comment
Я был сбит с толку тем, как сравнить сохраненный зашифрованный пароль в моей таблице базы данных и зашифрованный пароль с помощью предложения WHERE, но теперь это ясно. Теперь мой вопрос. Каково влияние на производительность, если нужно перебирать весь набор данных в базе данных. таблица пользователя для правильного пользователя?. Спасибо, Даниэль - person Mwesigye John Bosco; 02.03.2017