Хеширование пароля в PHP

Большинству современных PHP приложений доступна важная информация о пользователе, которая также храниться в базе данных (далее БД).
В качестве примера, рассмотрим веб приложение, осуществляющее регистрацию нового пользовател на сайте.
Так как же будут сохранены имя пользователя и пароль в БД?
Разрабатывая веб приложение на PHP мы всегда должны задумываться о безопасности.
Что произойдет, если вломщик получит доступ к нашей базе, а пароли в ней сохранены открытым текстом?
Он легко сможет прочитать все пароли пользователей. Вот почему мы использует прием под названием «хеширование пароля», который предотвращает раскрытие данных, в частности пароля, когда атакующий получил доступ к ним.
В этой статье мы научим вас безопасным приемам сохранения паролей в БД так, что даже попадя в руки злоумышленника, никакого вреда не будет нанесено.

Хэширование пароля

Процесс вычисления хэш-функции (хэширование) — не новая концепция. Оно используеться на практике уже долгое время.
Хеширование понимается как отпечаток пальцев. Каждый человек имеет свой, уникальные отпечаток пальцев. Подобным образом, каждая строчка текста имеет уникальный, фиксированного размера «цифровой отпечаток» называемый хэшем. Для хорошего алгоритма хэширования, две разные строки очень редко имеют одинаковый хэш (это называеться коллизией).

Реализация хэширования средствами PHP.

Существует различные алгоритмы для преобразования текста в хэш. Самые популярные: MD5, SHA1, Bcrypt. Каждый из этих алгоритмов поддерживается в PHP.

Пример процесса регистрации пользователя:
01  <?php
02	$username = $_POST["username"];
03	$password = $_POST["password"];
04
05	// create connection to database
06	// ...
07	 
08	// sanitize the inputs
09	// ...
10	 
11	// create an MD5 hash of the password
12	$password = md5($password);
13	 
14	// save the values to the database
15	$sql = "INSERT INTO users (username, password) VALUES (:username, :password)";
16	 
17	$stmt = $db->prepare($sql);
18	 
19	$stmt->execute(array(
20	    ":username" => $username,
21	    ":password" => $password
22	));
Следующий пример демонтстрирует процесс аутентификации пользователя:
01	<?php
02	$username = $_POST["username"];
03	$password = $_POST["password"];
04	 
05	// create connection to database
06	// ...
07	 
08	// sanitize the input
09	// ...
10	 
11	// create an MD5 hash of the password
12	$password = md5($password);
13	 
14	// retrieve the information from the database
15	$sql = "SELECT * FROM users WHERE username=:username AND password=:password";
16	$stmt = $db->prepare($sql);
17	$stmt->execute(array(
18	    ":username" => $username,
19	    ":password" => $password
20	));
21	 
22	$row = $stmt->fetch(); 


Хэширование пароля — следующий уровень
 
Следующий код демонстрирует использование SHA256 хэширование в PHP
1    <?php
2    $password = hash("sha256", $password);
 
PHP предлагает встроенную функцию hash(). Первым аргументом данной функции является имя алгоритма хэширования (вы можете использовать следующие имена алгоритмов хэширования: sha256, sha512, md5, sha1, а также многие другие). Вторым аргументов является строка текста, которую необходимо преобразовать в хэш. Результатом работы функции будет захэшированная строка.
 
Параноя со знаком плюс — «подсолим» пароль для увеличения секьюрности.
 
Следующий пример демонстрирует использование соли:
1    <?php
2    define("MAX_LENGTH", 6);
3     
4    function generateHashWithSalt($password) {
5        $intermediateSalt = md5(uniqid(rand(), true));
6        $salt = substr($intermediateSalt, 0, MAX_LENGTH);
7        return hash("sha256", $password . $salt);
8    }
 Сгенерируем соль при помощи функции uniqid().
 
Переходим на уровень выше: использование функции BCrypt.
1    <?php
2    function generateHash($password) {
3        if (defined("CRYPT_BLOWFISH") && CRYPT_BLOWFISH) {
4            $salt = '$2y$11$' . substr(md5(uniqid(rand(), true)), 0, 22);
5            return crypt($password, $salt);
6        }
7    }
 
Аутентифицируем пользователей:
1    <?php
2    function verify($password, $hashedPassword) {
3        return crypt($password, $hashedPassword) == $hashedPassword;
4    }
Заключение
под редакцией

Безопасность web-сайтов

Блог, посвященный обсуждению аспектов информационной безопасности веб-сайтов.

1 читатель · 45 топиков · RSS

0 комментариев

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.