GlassFish SHA-256 дайджест-аутентификация

Я хранил свои пароли в виде простого текста для целей разработки, но хочу вместо этого начать хранить хэши, но пока еще не удалось должным образом обеспечить GlassFish аутентификацию по хеш-паролю из-за следующей исключительной ситуации SecurityException:

SEVERE: jdbcrealm.invaliduserreason
WARNING: WEB9102: Web Login Failed: com.sun.enterprise.security.auth.login.common.LoginException: Login failed: Security Exception

Во-первых, я использую GlassFish 3.1 и настроил дайджест для моей области JDBC на SHA-256.

мой User класс имеет следующее поле аннотированного пароля:

@Basic(fetch = FetchType.LAZY)
@Column(length = 45, nullable = false)
private String password;

Следующий хелпер-метод отвечает за хеширование пароля:

private byte[] digest(String input) {
    byte[] output = null;
    try {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        output = md.digest(input.getBytes("UTF-8"));
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(RegistrationController.class.getName()).log(Level.SEVERE, null, ex);
    } catch (UnsupportedEncodingException ex) {
        Logger.getLogger(RegistrationController.class.getName()).log(Level.SEVERE, null, ex);
    }
    return output;
}

Затем я устанавливаю пароль для пользователя следующим образом:

u.setPassword(Base64.encode(digest(password)).toString());

Я бы не кодировал Base64, потому что это кажется недокументированным, но этот вопрос: Glassfish Security - jdbcRealm: Как настроить вход в систему с дайджестом SHA-256, говорит о том, что вам нужно это сделать.

Поэтому я предполагаю, что мне хотелось бы знать, ожидает ли GlassFish String (VARCHAR) или byte[] (BLOB) в качестве поля пароля в базе данных, правильно ли я хэширую пароль, и правильно ли он дополнительно кодировать Base64 хэш пароля?

Спасибо!

1 ответ

Решение

Ожидает ли GlassFish строку (VARCHAR) или байт [] (BLOB) в качестве поля пароля в базе данных?

Ожидается столбец, который отображается на тип Java java.lang.String в JDBC, и это, как правило, CHAR, VARCHAR и т. д. LOB не будут работать, так как реализация области JDBC выдает ResultSet.getString вызов метода для получения хэша пароля.

Правильно ли я хэширую пароль и правильно ли дополнительно Base64 кодировать хэш пароля?

Кодировка Base64 - не единственная поддерживаемая опция. Вы также можете выполнять шестнадцатеричное кодирование. Но вы должны выполнить любой из них и настроить JDBC Realm для выполнения того же во время выполнения. При отсутствии параметра кодирования Glassfish преобразует последовательность байтов, связанную с дайджестом, в последовательность символов в charset настроен для области.

Я подозреваю, что проблема связана с упоминанием кодировки UTF-8 в выражении input.getBytes("UTF-8"), Стоит проверить, соответствует ли кодировка Base64 результата, предоставленного вашим digest Метод фактически совпадает с хешами паролей, хранящимися в базе данных.

Кроме того, учитывая причину jdbcrealm.invaliduserreason Я также подозреваю, что может быть выполнено одно из следующих условий:

  • Параметр кодирования не указан для области JDBC; предпочтительно должен быть один из base64 или же hex (случай не имеет значения, исходя из исходного кода области JDBC), в противном случае вы окажетесь в сценарии, в котором массив байтов дайджеста преобразуется в массив символов (который, на мой взгляд, немного ненадежен, если вы не можете гарантировать что пароль, предоставленный пользователями, всегда находится в определенной кодировке).
  • Для пользователя в базе данных не существует хэша пароля. Смотрите мой предыдущий ответ по выполненному SQL-запросу; Возможно, вы захотите выполнить запрос самостоятельно. Вы можете регистрировать заявления, выпущенные Derby (если вы используете их в качестве базы данных), поместив файл с именем derby.properties в расположении вашей базы данных Derby со свойством derby.language.logStatementText=true в этом. При закрытии базы данных файл derby.log будет заполнен всеми запросами, выполненными сервером приложений.
  • Оператор SQL, подготовленный Glassfish, неверен.
  • Соединение с базой данных не может быть установлено.
Другие вопросы по тегам