Шифрование паролей с помощью Spring/Hibernate — Jasypt или что-то еще?

В стеке приложений Java с Spring & Hibernate (JPA) на уровне доступа к данным, каковы хорошие методы применения шифрования паролей (надеюсь, с использованием аннотаций) и где вы можете узнать больше о том, как это сделать (руководство и т. д.)?

Понятно, что я буду использовать JCA поддерживаемый алгоритм шифрования паролей, но я бы предпочел не реализовывать логику оболочки, если есть простой способ.

Я смотрел на Jasypt и а) задавался вопросом, хороший ли это вариант и как это сделать и б) что еще люди используют для этого. Если кто-то использует Jasypt или его альтернативу, было бы здорово узнать подробности о вашем опыте.


person stevedbrown    schedule 02.07.2009    source источник
comment
Я всегда сохранял хэш пароля, а не фактический пароль. Таким образом, вы все еще можете проверить его, но вы не несете никакой ответственности за его хранение.   -  person Jesse    schedule 02.07.2009
comment
Правильно, это именно то, что я хочу сделать - просто пытаюсь найти библиотеку, которая поможет с хешированием + запросом на уровне ORM.   -  person stevedbrown    schedule 02.07.2009


Ответы (6)


В Java уже есть все необходимые библиотеки. Просто создайте служебный метод, реализующий хеширование с солью, как описано в OWASP.

Если вы действительно не хотите владеть этим кодом и не возражаете против дополнительной зависимости, кажется, что Библиотека Shiro (ранее JSecurity) содержит реализация того, что описано в OWASP.

Также похоже, что упомянутая вами библиотека JASYPT имеет похожая утилита.

Я понимаю, что в этом ответе не упоминаются Spring или Hibernate, но я не понимаю, как вы надеетесь использовать их в этом сценарии.

person laz    schedule 02.07.2009
comment
Где вы пытаетесь зашифровать пароль базы данных в файле конфигурации спящего режима? Как ты это сделал? У меня проблемы с спящим режимом 5. - person pitchblack408; 08.08.2018
comment
@pitchblack408, это для сокрытия паролей в данных приложения, например, для пользователей системы, а не пароля, используемого для открытия соединения с базой данных. - person laz; 09.08.2018
comment
Спасибо, я вижу, что теперь, прочитав всю документацию - person pitchblack408; 09.08.2018

Вы можете использовать Jasypt с Hibernate для шифрования или хеширования ваших свойств на лету, если это то, что вам нужно. находясь в поиске. Фактический алгоритм вычисления дайджестов (хэшей) довольно прост с использованием JCE, если вы также хотите свернуть свой собственный.

person Kevin    schedule 02.07.2009
comment
Я не думаю, что подход JASYPT с Hibernate идеален для паролей, поскольку можно расшифровать значение. Пароли должны быть безопасными с односторонним дайджестом. - person laz; 02.07.2009
comment
JASYPT поддерживает это — jasypt.org/howtoencryptuserpasswords.html. - person stevedbrown; 02.07.2009
comment
Я видел это, но не похоже, чтобы интеграция Hibernate, которую они предоставляют, использовала это. Интеграция Hibernate предназначена только для шифрования/дешифрования, а не для одностороннего переваривания. - person laz; 02.07.2009
comment
Я изучил это, и Лаз прав - шифрование в спящем режиме не основано на дайджесте и поэтому не подходит для паролей. Судя по документации, StrongPasswordGenerator Jasypt будет работать. - person Will Sargent; 31.03.2011

Подойдет MD5 или SHA-256, хотя сейчас MD5 можно взломать.

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

В спящем режиме просто сохраните как строку. На стороне проверки есть такой метод, как:

public validate(String user, String pass)
{
    if(getUser(user).getPass().equals(getHash(pass)))
        return true;
    return false;
}
person Jesse    schedule 02.07.2009
comment
Тот же комментарий, я не искал архитектуру или алгоритм для использования - просто то, как люди это делают на самом деле. - person stevedbrown; 02.07.2009
comment
Это больше то, что вы ищете? evolt.org/node/60122 - person Jesse; 02.07.2009
comment
Это описывает то, что я делаю сейчас - мне было интересно, есть ли способ аннотировать свойства гибернации или что-то, чтобы сделать это автоматически. Кажется чище. - person stevedbrown; 02.07.2009
comment
Я никогда не встречал ничего подобного. Вы можете исправить свой собственный AOP pointcut, чтобы сделать это на основе аннотации, но это кажется излишним для этого сценария. - person Jesse; 02.07.2009

Кажется, нет специального способа Hibernate сделать это с Jasypt, но вы можете настроить шифратор паролей в Spring:

  <!-- 
   Set up string digester here so we can configure it for more pools if it's a problem... 
  -->
  <bean id="stringDigester" class="org.jasypt.digest.PooledStringDigester">
    <!-- same settings as StrongPasswordGenerator -->
    <property name="poolSize" value="2"/>
    <property name="algorithm" value="SHA-256"/>
    <property name="iterations" value="100000"/>
    <property name="saltGenerator">
      <bean class="org.jasypt.salt.RandomSaltGenerator"/>
    </property>
    <property name="saltSizeBytes" value="16"/>
  </bean>

  <!-- ...and then we only have to deal with the passwordEncryptor interface in code. -->
  <bean id="passwordEncryptor" class="com.myproject.util.StringPasswordEncryptor">
    <property name="stringDigester" ref="stringDigester"/>
  </bean>

После этого вы вызываете context.getBean("passwordEncryptor"), чтобы получить шифровальщик, а затем вызываете encryptPassword() или checkPassword().

person Will Sargent    schedule 31.03.2011

Если вы используете Spring в своем приложении, вы также можете использовать Spring Security, который предоставляет вам с несколькими кодировщиками паролей, например ShaPasswordEncoder Вы можете найти его на StackOverflow

person mwojtera    schedule 08.08.2013

Я просто использую что-то похожее на SHA-256(username + ":" + password + ":" + salt) и сохраняю его в базе данных в 64-символьном столбце с именем passwd.

Википедия говорит о солях: «Данные с солью усложняют атаки по словарю, которые используют предварительное шифрование записей словаря: каждый используемый бит соли удваивает объем памяти и требуемых вычислений. ... Для лучшей безопасности значение соли держится в секрете, отдельно от базы данных паролей. Это дает преимущество, когда база данных украдена, а соль — нет».

Таким образом, для аутентификации получите пользователя из базы данных с предоставленным именем пользователя, затем сгенерируйте тот же хэш, используя пароль, предоставленный при попытке входа в систему, и сравните его с тем, что находится в базе данных. Также добавьте некоторое ограничение скорости для попыток входа в систему (например, 5 за 5-минутный период). Если пользователь забудет свой пароль, НИКОГДА не отправляйте ему по электронной почте пароль (поскольку он не будет сохранен) и не отправляйте ему по электронной почте новый сгенерированный пароль, а отправляйте ему по электронной почте ссылку для изменения этого пароля с помощью ключа смены пароля/одноразового номера/соли в URL-адрес, который вы можете проверить.

person JeeBee    schedule 02.07.2009
comment
Я отредактировал свой вопрос - я искал не алгоритм, а стандартный (то есть реализованный библиотекой) способ использования алгоритмов JCA со стеком Spring/Hibernate. - person stevedbrown; 02.07.2009
comment
Итак, вам действительно нужно что-то вроде ‹code›@Password(SHA-256)‹/code› аннотации к полю в вашей модели учетной записи пользователя, и чтобы ваша структура автоматически выполняла проверку в фоновом режиме? В какой-то момент вы начинаете просить фреймворк быть слишком конкретным с точки зрения функциональности и жертвовать гибкостью. - person JeeBee; 03.07.2009