Безпечне зберігання солі
Що безпечніше і чому:
- зберігати одну загальну сіль для всіх паролів користувачів в змінній середовища
- або зберігати свою сіль для кожного користувача в тій же таблиці, що і хеші?
Відповіді на питання (1)
Розглянемо варіанти детальніше
Варіант 1. Зберігати одну загальну сіль для всіх паролів користувачів поза БД
hash(secret + password)
На перший це виглядає безпечніше, адже якщо хтось отримає доступ до БД, то солі у ньому не буде, і напевно відновити паролі не зможе? ..
Але якщо зловмисник отримає доступ і до БД, і до солі зі змінної середовища, то для добування паролів все одно треба буде будувати райдужну таблицю. І якщо у вас одна сіль на всіх користувачів, то це зробити набагато простіше. Інша проблема з безпекою: якщо зловмисник (або його співучасник/жертва) має доступ до системи як користувач, то він вже знає 1 пароль і його хеш, можливо зможе змінювати пароль і дивитися зміну хеша, знаходити в БД інших користувачів з таким же паролем...
Цей варіант схожий на принцип Security through obscurity (безпека через неясність/заплутування), а цього принципу радять уникати і покладатися на сильніші криптографічні методи.
Варіант 2. Зберігати свою для кожного користувача сіль в БД з хешамі паролів
hash(salt + password)
В цьому випадку, якщо зловмисник отримає доступ до БД, то разом з хешами паролів він отримає і солі до них. Але тепер для отримання паролів треба буде згенерувати не одну райдужну таблицю на всіх, а для кожного користувача свою! При цьому, важливо коректно реалізувати свою систему роботи з користувачами: при зміні пароля треба міняти і сіль, щоб навіть маючи стару версію БД, зловмисник вже не зміг отримати з цього вигоду.
Цей же спосіб використовується в Django, також його радять і обгрунтовують в аналогічному питанні на enSO - раджу почитати, там обговорені різні варіанти і їх обгрунтування.
Питання насправді спірне і залежить від реалізації вашої системи. Якщо у вас лише 1 або кілька серверів з повним або слабо захищеним доступом один до одного, то швидше за все зловмисник отримавши доступ до БД, легко отримає доступ і до ОС зі змінними оточення, і навпаки, що нівелює сенс першого варіанту. Якщо ж у вас велика і продумана інфраструктура, доступи до БД і серверів з кодом розмежовані, налаштовані жорсткі групи безпеки, всюди використовуються користувачі з обмеженнями і в БД, і в ОС, то можна отримати вигоду з першого способу. Тому є наступний варіант.
Варіант 3. Змішати обидва варіанти
Можна поєднати краще від двох світів, наприклад так:
hash(hash(salt + secret) + password)
Хоча є й інші варіанти, деталі можна знайти все в тому ж питанні . Але знову ж таки, користі в цьому не сильно більше, ніж у другому варіанті, особливо якщо ваша серверна інфраструктура слабо захищена.