Главное меню
Как хранить пароли
В общем-то, несмотря на громкий заголовок, я не знаю как Хочу просто рассказать какие задачи перед собой ставил и как их решил.
 
Нужно было чтобы клиент мог проходить авторизацию на сайте через веб форму или автоматически через cookie.
 
Самый простой способ - записали пароль в БД и в куки положили его же. Проверяем, если значение в БД равно значению в куках - здравствую Вася.
 
Теория проста, но на практике такой подход несет кучу проблем: достаточно получить доступ к кукам или БД и все ваши пользователя получат кучу неприятностей. По вашей, кстати, вине.
 
По этой причине обычно хранят хэш пароля. Хэш - это такая контрольная сумма, которая получена при помощи необратимого шифрования исходной строки. В определенных рамках она сравнительно уникальна, для одной и той же последовательности она постоянна, хэши двух похожих строк совершенно не похожи и из нее нельзя восстановить первоначальную последовательность.
 
Получается что все просто: создал хэш пароля, положил его в БД, а при проверке пароля просто сравнивать хэши. Но если пользователь забыл пароль, то старый ему подсказать не получится - придется создавать новый. Такова плата за безопасность.
 
Ну вроде все придумали: в базу - хэш пароя, в куки - хэш пароля (некоторые, впрочем, не заморачиваются хэшем в куках, ну да им видней). Живи, да радуйся. Но тут выползают несколько неприятных моментов:
 
1. В случае взлома БД обладатель хэша получает возможность войти под учеткой пользователя, подставив хэш в куки.
2. Алгоритмы хэширования общеизвестны, так что можно узнать пароль просто перебором.
3. Для большого количество возможных паролей уже посчитаны хэши, так что распространенные пароли даже подбирать не нужно.
 
Некоторые в таких случаях просто делают двойной хэш: сначала хэш пароля, а потом хэш хэша. Собственно, можно делать и тройной, четверной и так далее. Проблема в том, что у меня система с открытым кодом, поэтому такая уловка не сработает. То есть она, конечно, защитит от пункта 3, но первые два по прежнему никуда не делись.
 
Так же есть возможность "посолить" пароль Перед хэшированием к паролю добавляется "соль". Она хранится рядом с паролем, что позволяет предотвратить поиск пароля по таблице хэшей, а так же поиск одинаковых паролей (ведь мы помним что у одинаковых паролей и хэш одинаковый).
 
Выглядит это примерно так:
PHP
$hash=md5($salt.$pass);

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

//$salt генерируется один раз при установке системы
//и хранится в файле настроек сайта
$salt=md5(microtime());
 
//пароль пользователя
$pass='password';
 
//этот код мы храним в куках и используем для автоматической авторизации
$cookiehash=md5($pass.$salt);
 
//этот код хранится в БД
$dbpass=md5($cookiehash.$salt);
 

 
В результате получается что соль и хэш мы храним в разных местах: соль в файловой системе сервера, хэш - в БД, а еще один хэш - у пользователя в куках. Так что каждый из хэшей сам по себе практически бесполезен, в плане получения пароля.
Правда, существует возможность подбора коллизии для секретного кода на основании информации из собственных кук. Но помимо трудоемкости этого процесса, необходимо еще получить данные из БД или кук пользователя.
 
Вот такие мысли.
Описанная схема только планируется для реализации? А как же сейчас утроена авторизация?
 
И каким образом можно обезопасить себя от вышеописанного подбора колизии? Если ли решения?
Это сейчас так работает. Коллизия - это совсем не значит совпадение исходника, это означает только совпадение хэша. С другой стороны, длинна исходника известна, так что это несколько снижает круг поиска (на несколько десятков лет
Для усиления защиты можно сделать соль переменной длинны. В этом случае имея коллизию нельзя быть до конца уверенным что что ты имеешь на руках именно соль.
Тоесть без серьезной подготовки и огромных вычислительных мощностей подобрать/расшифровать пароль крайне маловероятно?
Именно.
Кроме того, в следующей сборке при установке соль будет случайным образом изменяться от 32 до 64 символов. Думаю, это должна быть достаточная защита от ее подбора.