Языки программирования

Функция md5 в PHP

В этой статье я решил затронуть тему MD5 хэширования. Самый простой пример использования MD5 хэша — это шифрование паролей пользователей. Ведь не секрет, что если хранить пароли в открытом виде в базе данных, то при её утере, все пароли пользователей будут украдены. И вот тут на помощь приходит функция хэширования в PHP.

MD5 (Message Digest 5) — 128-битный алгоритм хеширования, разработанный профессором Рональдом Л. Ривестом из Массачусетского технологического института в 1991 году. Предназначен для создания «отпечатков» или дайджестов сообщения произвольной длины и последующей проверки их подлинности.

Функция MD5 хэширования в PHP называется md5(). Принимает функция одну строку, которую необходимо зашифровать. Пример использования md5():
<?php
$str = 'яблоко';

if (md5($str) === '1afa148eb41f2e7103f21410bf48346c') {
    echo "Вам зеленое или красное яблоко?";
}
?>
Пример скрипта проверки логина и пароля:
<?php
  $login = "DemoAdmin";
  $password = "48503dfd59720bd5ff56c102065a52d7"; //В реальности считывается из БД
  if (($_GET['login'] == $login) && (md5($_GET['password']) == $password)) echo "Привет, Хозяин!";
  else echo "Ты не Хозяин!";
?>

Свойства md5 хеширования

  • MD5-хэш содержит 32 символа;
  • MD5-хэш уникален для каждой строки;
  • Процесс MD5-хэширования необратим;
  • Процесс MD5-хэширования достаточно медлителен.

Немного безопасности

Достоинства хеширования заключается в том, что хакеру сложно узнать реальный пароль, который нужно вводить. Обратное преобразование можно сделать только банальным перебором. Нужно запускать цикл, который будет хешировать все допустимые значения и сравнивать результат с нужной хеш-суммой.
Вроде сложно? Но есть одна проблема — хеши статичны. Хакер может один раз сгенерировать одну большую таблицу, в которой будут находиться все возможные значения и соответствующие им хеши. Найти пароль таким образом очень просто.
Чтобы хакеру не было так просто задачу можно и нужно усложнить. Просто перед шифрованием надо добавлять к паролю какой-то символ или строку:
$pass = md5($_GET[password]."sjwsffr241");
Теперь таблица хакера бесполезна. Хакеру придется генерировать новую таблицу, в которой все значения перед хешированием тоже объединяются с этой бессмысленной строкой.

Строка, которую мы добавили к паролю перед шифрованием, называется «солью». Мы ка бы «подсалили» шифруемый текст и сделали его безопасным.

Теперь, чтобы самому проверить введеный пользователем пароль на соответствие этому хешу, делаем так:
$query = mysqli_qyery(SELECT * FROM Users WHERE (name = '$_GET[name] ".
"AND pass = " . md5($_GET[password]."sjwsffr241") . "'");
Если у Вас небольшой сайт, то этой защиты будет достаточно, потому что хакер не будет надрываться ради единичного взлома. Но если это большой сайт или форум, то хакер может потратить время и сгенерировать таблицу, в которой будут все возможные хеши для строк, объеденённых с «солью» sjwsffr241.

В этом случае можно для каждого пароля случайным образом генерировать свою «соль» и использовать её. Например:
$salt = сгенерировать значение;
$password = md5($_GET[password].$salt);

$query = mysqli_qyery(INSERT INTO users (name, password, salt) ".
"VALUES ('$_GET[name]', "$password", $salt')";
Теперь проверка пользователя может выглядеть так:
$_GET[users] = addslashes($_GET[users]);
$result = mysqli_query("SELECT salt FROM Users WHERE
         name = '$_GET[name]'");

if (list($salt) = mysqli_fetch_row($result))
{
$query = mysqli_query("SELECT * FROM Users WHERE (name = '$_GET[name] ".
"AND password = '" . md5($_GET[password]."$salt") . "'");
$rows = mysqli_num_rows($query);
if ($rows == 1)
  {
// Пользователь есть в БД
  }
}
else
  die "Пароль неверен!";
Самоучитель по PHP