GlassFish SHA-256 дайджест-аутентификация - PullRequest
2 голосов
/ 28 июля 2011

Я хранил свои пароли в виде простого текста для целей разработки, но хочу вместо этого начать хранить хэши, но пока еще не удалось должным образом обеспечить 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 - jdbcRealm: Как настроить вход в систему с SHA-256-дайджестом предполагает, что вам нужно это сделать.

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

Спасибо!

1 Ответ

2 голосов
/ 28 июля 2011

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

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

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

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

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

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

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