4

Что более безопасно и чем:

  • хранить одну общую соль для всех паролей пользователей в переменной среды
  • или хранить свою для каждого пользователя соль в той же таблице, что и хэши?
tetelevm
  • 724
  • 1
    Конкатенируй прямо к хэшу, чтобы он был внешне похож на хэш другого формата... – Akina Oct 06 '20 at 05:40
  • @Akina то есть, лучше в базе, но у каждого пользователя своя? – tetelevm Oct 06 '20 at 05:47
  • В причинах, по которым можно отдать голос за закрытие темы, есть "Невозможно дать объективный ответ. Скорее всего, ответы на этот вопрос будут основаны на мнениях, а не на фактах и цитатах. Необходимо переформулировать его так, чтобы на него можно было дать объективный ответ." Самый Ваш случай. – Akina Oct 06 '20 at 05:49
  • @Akina вопрос "как сложнее будет злоумышленникам - украсть соль из переменных среды или работать с кучей известных солей" лучше? – tetelevm Oct 06 '20 at 05:54
  • 3
    Да пусть крадут! Алгоритм надо прятать, а не соль. – Akina Oct 06 '20 at 05:55
  • @Akina так большинство же вопросов инженерных и связанных с безопасностью не имеют одного универсально верного ответа и зависят от многих обстоятельств. Но это же не значит, что все такие важные тем надо запрещать обсуждать?) Лучше не полениться и описать разные варианты, их плюсы и минусы, границы применимости, best practices. И в аналогичном вопросе на enSO дали несколько хороших ответов. – AivanF. Oct 06 '20 at 06:21
  • 1
    @AivanF. Ну так и задавать вопрос надо по конкретной ситуации, нормально её описывая. А "как оно там вообще" - это не на один том потянет... и всё равно, что ни напиши, к любому варианту легко прикладывается "хотя в случае, когда..." - и ещё плюс один многотомник. Со своими "хотя в случае"... – Akina Oct 06 '20 at 06:28
  • @Akina оно как бы так, но что человек без опыта ещё скажет? Может он делает небольшой учебный проект или книгу читает, просто заинтересовался темой и решил узнать плюсы, минусы и границы применимости разных вариантов? А таких общих вопросов у нас много, чтобы называть их оффтопиком: 1 2 3 4 4. – AivanF. Oct 06 '20 at 07:24
  • @AivanF Давайте без вот этих демагогий, а? Есть установленные на ресурсе нормы, в частности Stack Overflow на русском > Справка > Как задавать вопросы > Какие вопросы лучше не задавать?. И там чётко всё расписано, включая "Обсуждения на любые темы, пересекающиеся с тематикой сайта, приветствуются в чате, но не на самом сайте вопросов и ответов." Вот и добро пожаловать. что человек без опыта ещё скажет? В данном случае, вероятно "Правила проглядел по диагонали, справку не читал вообще, но мне надо вотпрямщас, так что уж простите и поймите." – Akina Oct 06 '20 at 07:31
  • @Akina, на вопрос можно дать объективный ответ, где вы видите проблему? Если ответ тянет не на один том, это не значит, что он не объективный и основан на мнениях. – eanmos Oct 06 '20 at 11:05
  • @eanmos Просто представьте, что есть дополнительные сведения, которые не указаны. И они такие: имеется свободный доступ к таблицам БД, в принципе не имеется доступа к переменным среды сервера, в т.ч. удалённо (неважно, как именно это сделано, но так есть). И однозначный объективный ответ будет каким? вариант 1... Теперь возьмём другие неуказанные условия: любой имеет свободный доступ к консоли для просмотра переменных среды, в принципе не имеется доступа к таблице пользователей (опять неважно как это сделано). Угу, вариант 2... Вы всё ещё уверены, что "на вопрос можно дать объективный ответ"? – Akina Oct 06 '20 at 11:15
  • @Akina, конечно, вы можете рассмотреть один или несколько вариантов в вашем ответе и он будет объективен. Я не говорю о полноте ответа, да, для ответа на некоторые вопросы нужно писать целые книги, но неполный ответ -- не значит необъективный. Другими словами, вы немного путаете полноту и объективность. – eanmos Oct 06 '20 at 11:30
  • @eanmos Объективный ответ, отвечающий на другой вопрос, не теряет объективности - только толку в нём ноль для вопрошающего. А для того, чтобы дать объективный ответ на именно заданный вопрос, с учётом всех, в т.ч. неназванных, обстоятельств и условий, нужно сначала вытрясти из автора эти обстоятельства и условия. Впрочем, если он впоследствии обнаружит, что из-за излишней лаконичности он ориентировался на ответ объективный, но в его конкретных условиях не очень корректный, а то и вовсе неприменимый - это его проблемы. – Akina Oct 06 '20 at 11:40
  • @Akina, толку никогда не будет ноль, т. к. даже если ситуация автора полностью не описывается ответом, он получит новые знания и переймет опыт отвечающего. Более того, при написании ответа нужно ориентироваться не столько на автора вопроса, сколько на всех людей, что прочтут этот вопрос/ответ в дальнейшем. – eanmos Oct 06 '20 at 12:15
  • 1
    @Akina я хотел не чтобы помогли решить конкретный практический вопрос, а хотел узнать более правильную практику решения этой темы. Мне ответили на вопрос и добавили, что безопасности много не бывает, в итоге я понял, как стоит делать, а если кто-то тоже заинтересуется этим вопросом, то может найти на него здесь ответ. Так что ответы вполне были толковыми, я считаю. – tetelevm Oct 06 '20 at 12:22

2 Answers2

4

Рассмотрим варианты детальнее

Вариант 1. Хранить одну общую соль для всех паролей пользователей вне БД

hash(secret + password)

С виду это выглядит безопаснее, ведь если кто-то получит доступ до БД, то соли у него не будет, и наверное восстановить пароли не сможет?..

Но если злоумышленник получит доступ и к БД, и к соли из переменной среды, то для извлечения паролей всё равно надо будет строить радужную таблицу. И если у вас одна соль на всех юзверей, то это гораздо сделать проще. Другая проблема с безопасностью: если злоумышленник (или его соучастник/жертва) имеет доступ к системе как пользователь, то он уже знает 1 пароль и его хэш, возможно сможет менять пароль и смотреть изменения хэша, находить в БД других пользователей с таким же паролем...

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

Вариант 2. Хранить свою для каждого пользователя соль в БД с хэшами паролей

hash(salt + password)

В этом случае, если злоумышленник получит доступ к БД, то вместе с хэшами паролей он получит и соли к ним. Но теперь для извлечения паролей надо будет сгенерировать не одну радужную таблицу на всех, а для каждого пользователя свою! При этом, важно корректно реализовать свою систему работы с юзерами: при смене пароля надо менять и соль, чтобы даже имея старую версию БД, злоумышленник уже не сможет извлечь из этого выгоду.

Этот же способ используется в Django, также его советуют и обосновывают в аналогичном вопросе на enSO – советую почитать, там обсуждены разные варианты и их обоснования.


Как упомянули в комментариях, вопрос на самом деле спорный и зависит от реализации вашей системы. Если у вас лишь 1 или несколько серверов с полным или слабо защищённым доступом друг до друга, то скорее всего злоумышленник получивший доступ к БД, легко получит доступ и к ОС с переменными окружения, и наоборот, что нивелирует смысл первого варианта. Если же у вас большая и продуманная инфраструктура, доступы к БД и серверам с кодом разграничены, настроены жёсткие группы безопасности, везде используются юзеры с ограничениями и в БД, и в ОС везде, то можно поиметь выгоду с первого способа. Поэтому есть следующий вариант.

Вариант 3. Смешать оба варианта

Можно совместить лучшее от двух миров, например так:

hash(hash(salt + secret) + password)

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

AivanF.
  • 9,858
3

Ни то ни другое.

  1. Для каждого юзера своя соль - очевидность этого даже не требует доказательств, если будет 1 соль, то под эту соль для всех юзеров генерируется 1 радужная таблица, что существенно облегчает задачу атакующего
  2. Соль необходимо хранить отдельно от хэшей. Желательно даже в разных БД, ну или хотя бы в разных таблицах.
  3. Поскольку соль по своей природе открыта, то желательно озаботиться перцем (pepper), который в отличие от соли надо хранить в секрете: key = hash(password+pepper+salt)
Barmaley
  • 81,300