В большинстве современных приложений PHP, доступ к важной информации пользователя хранится в базе данных. Например, веб-приложение может иметь систему регистрации для новых пользователей. Но как нужно хранить имена и пароли пользователей в базе данных?
Предположим, у вас есть хэшированный пароль пользователя, и хранится он в таблице базы данных. Даже если взломщик получает доступ к нашей базе данных, он не сможет определить исходный пароль. Но, если взломщик видит одинаковые хэши, он может сделать вывод о том, что пароли для этих учетных записей одинаковые. Если атакующий, знает хотя бы один пароль к аккаунту, он может его использовать для получения доступа ко всем аккаунтам с этим паролем.
Решение состоит в использовании случайного числа при генерации хэша, называемым солью. Более простыми словами, соль - это кусочек дополнительных данных, которые делают ваши хэши намного более устойчивыми к взлому. Каждый раз, когда мы генерируем хэш пароля, мы используем случайную соль. Вам просто нужно генерировать случайное число определенной длины и добавить его в текстовый пароль, а затем его хэшировать. Таким образом, даже если пароли для двух аккаунтов одинаковые, сгенерированный хэш не будет одинаковым, потому что числа соли, в одинаковых случаях различные.
define("MAX_LENGTH", 6);
function generateHashWithSalt($password) {
$intermediateSalt = md5(uniqid(rand(), true));
$salt = substr($intermediateSalt, 0, MAX_LENGTH);
return hash("sha256", $password . $salt);
}
Чтобы создать соль мы используем функцию uniqid(). Первый аргумент является rand() — который генерирует случайное число. Вторым аргументом является true — это увеличит шанс уникальности генерируемого числа.
Для аутентификации пользователя, вы должны хранить число соль, используемого для хэширования паролей (можно хранить соль в другом столбике в той же таблице, где у вас хранятся имя пользователя и пароль). Когда пользователь пытается войти в систему, добавить соль введенный пароль, а затем хэш с его хэш-функцией.
Вообще, хеширование на основе md5 и SHA-1 стоит признать устаревшим. В md5 существует немало коллизий, а также к нему рассчитаны довольно большие и общедоступные радужные таблицы. Ситуация с SHA-1 лишь немногим лучше. Использование соли и более стойких алгоритмов хеширования значительно увеличивают надёжность, однако рассчёт даже длинных хешей — не очень сложная задача для современных систем, особенно с тех пор как для рассчётов стали привлекать GPU. Поэтому для увеличения надёжности шифрования паролей следует использовать такой алгоритм, который будет работать настолько медленно, что рассчёт радужных таблиц и атаки методом перебора станут абсолютно неэффективными.