Хранение хеша в виде массива байтов с помощью JPA

Мой класс сущности User содержит поле хэша пароля, которое представляет собой массив байтов с фиксированной длиной (32, поскольку это хэш SHA-256).

@Entity
public class User {
    @Column(nullable=false)
    private byte[] passwordHash;
    ...
}

Как видите, я не аннотировал его ничем особенным, просто NOT NULL.

Это работает, но будет ли это работать? Моя схема генерируется Hibernate, но я точно не знаю, что она генерирует (в настоящее время я использую базу данных HSQL в памяти).

Я обеспокоен тем, что, поскольку он не знает, что это массив фиксированной длины (поле length аннотации Column применяется только к строкам), он будет хранить этот хэш в поле BLOB, которое добавляется в запись как указатель (если я правильно понимаю, как работают базы данных).

Так ли это, и как я могу это изменить? Должен ли я просто кодировать хэш как строку с base64 или hex, принимая небольшое влияние на производительность/правильность?


person Bart van Heukelom    schedule 29.09.2010    source источник
comment
Почему бы вам не попробовать это с фактической целевой базой данных и посмотреть, что она сгенерирует?   -  person skaffman    schedule 29.09.2010
comment
@skaffman: я изменил базу данных на MySQL, и она генерирует столбец TINYBLOB.   -  person Bart van Heukelom    schedule 29.09.2010
comment
Хотя я полагаю, что это не на самом деле имеет значение. Я никогда не буду индексировать по хэшу пароля, и мне нужно будет читать его только для одной записи за раз. Я все еще заинтересован в том, чтобы сделать его идеальным, хотя для академических целей.   -  person Bart van Heukelom    schedule 01.10.2010


Ответы (4)


Я обеспокоен тем, что, поскольку он не знает, что это массив фиксированной длины (поле длины аннотации столбца применяется только к строкам), (...)

Если вы укажете длину столбца, Hibernate будет использовать эту информацию для определения типа столбца SQL для генерации (TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB).

Мне нужен ДВОИЧНЫЙ (32)

Вы пробовали это?

@Column(columnDefinition="BINARY(32) NOT NULL")
private byte[] passwordHash;
person Pascal Thivent    schedule 09.10.2010

tinyblob — это хорошо (справочник по типам mysql), но все мои приложения отлично работают со строками. . Если вас действительно волнуют миллисекунды, попробуйте обе версии в профилировщике и посмотрите, что работает лучше всего. Я предпочитаю профилировщик, включенный в netbeans.

person klause    schedule 01.10.2010

Насколько я знаю, хэш SHA-256 всегда состоит только из печатных символов (а если нет, кодируйте его base64), поэтому решение состоит в том, что вы МОЖЕТЕ сохранить его как строку, а затем использовать поле length аннотации Column.

Тогда у вас есть фиксированная длина и нет сомнений в производительности.

person lImbus    schedule 08.10.2010
comment
Нет, я видел вывод, и он действительно состоит в основном из непечатаемых символов (точнее, вообще не является символьными данными). Я мог бы, конечно, закодировать его в base64 или hex, но если бы я мог хранить его в чистом двоичном виде, это было бы неплохо. - person Bart van Heukelom; 11.10.2010

Это может быть не так эффективно, но я предлагаю вам использовать String в качестве типа хранилища и транслировать по мере необходимости с помощью методов получения и установки. Это обеспечивает максимальную переносимость JPA между различными базами данных.

Я использую аналогичную технику с датой/временем, сохраняя длинные значения, которые представляют время с эпохи в формате UTC, что позволяет мне избежать проблем с часовым поясом (информация о часовом поясе не переносима в датах базы данных во всех базах данных).

person Archimedes Trajano    schedule 19.03.2012