Защита паролей в PHP
Не рекомендуется хранить пароли пользователей вашего сайта в открытом виде. Если кто-либо завладеет доступом к вашей базе данных, он легко узнает пароли всех пользователей. Лучшим решением будет шифрование пароля необратимыми хеш функциями. Это значит, что функция шифрования преобразует пароль в некую случайную строку, из которой будет не возможно узнать оригинальный пароль.
В PHP имеются две такие хеш функции: md5() и sha1(). Принцип их работы схож, но многие склоняются к выбору sha1(), аргументируя это тем, что MD5 уже несколько раз был скомпрометирован. Я лично разницы в их использовании не вижу. Единственно, что md5() генерирует зашифрованную строку из 32 символов, а sha1() из 40 символов. Рассмотрим принцип действия на примере:
<?php $password = 'roshan'; //оригинальный пароль $encrypt = d6dfb33a2052663df81c35e5496b3b1b; //его хеш if(strcmp(md5($_POST['pass']),$array['pass']) == 0) echo "Пароль введен не верно!"; else echo "Пароль правильный!"; ?>
Когда пользователь вводит логин и пароль в форму, мы шифруем введенный пароль и проверяем с зашифрованным оригинальным паролем. Дальнейшая работа скрипта возможна только при совпадении обеих строк. Поэтому при регистрации пользователя, пароль следует шифровать, и хранить уже в зашифрованном виде.
Но обычно пары логин/пароль хранят в базе данных. К тому же здесь отсутствует проверка входящих данных. Поэтому немного изменим наш скрипт аутентификации:
<?php // Получаем переменные и обрабатываем их $login = addslashes(htmlspecialchars(substr($_POST['login'], 0, 20))); $pass = addslashes(htmlspecialchars(substr($_POST['pass'], 0, 20))); // Соединяемся с базой данных $link = mysql_connect(localhost,USERNAME,PASSWD) or die("Connection trouble!"); mysql_select_db(DBNAME,$link) or die("Error!"); // Запрос пользователя $query = mysql_query("SELECT * FROM users WHERE login LIKE '$login'"); $array = mysql_fetch_assoc($query); // Проверка пароля if(strcmp(md5($pass,$array['password']) == 0) echo "Пароль введен не верно!"; else echo "Пароль правильный!"; ?>
Ну вот, уже лучше. Однако не совсем. Хотя сам md5 или sha1 хеш не поддается простому перебору (брутфорс), в настоящее время растут словари хешей. Многие пользователи используют слишком короткие пароли, что позволяет находить около 30% паролей (по грубым расчетам) по словарям хешей. От этого можно спастись добавлением случайной строки к паролю, что существенно изменит конечный хеш. Это нужно сделать при шифровании и при проверке пароля. Данная практика является рекомендуемой и добавляет определенный уровень безопасности вашим скриптам.
<?php // Получаем переменные и обрабатываем их $login = addslashes(htmlspecialchars(substr($_POST['login'], 0, 20))); $pass = addslashes(htmlspecialchars(substr($_POST['pass'], 0, 20))); // Соединяемся с базой данных $link = mysql_connect(localhost,USERNAME,PASSWD) or die("Connection trouble!"); mysql_select_db(DBNAME,$link) or die("Error!"); // Запрос пользователя $query = mysql_query("SELECT * FROM users WHERE login LIKE '$login'"); $array = mysql_fetch_assoc($query); // Модифицируем введенный пароль $sault = '@d93sF'; // эта строка также должна быть добавлена к паролю при регистрации $new_pass = $pass . $sault; // Проверка пароля if(strcmp(md5($new_pass,$array['password']) == 0) echo "Пароль введен не верно!"; else echo "Пароль правильный!"; ?>