Статьи ⇒ Шифрование ⇒ Защита паролей в PHP

Защита паролей в PHP

Опубликовано: 24 май 2011 в 00:15
Автор: freeeeez  

Не рекомендуется хранить пароли пользователей вашего сайта в открытом виде. Если кто-либо завладеет доступом к вашей базе данных, он легко узнает пароли всех пользователей. Лучшим решением будет шифрование пароля необратимыми хеш функциями. Это значит, что функция шифрования преобразует пароль в некую случайную строку, из которой будет не возможно узнать оригинальный пароль.

В 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 "Пароль правильный!";
?>
Источник: Roshanbh внешняя ссылка
Тэги:  •  • 
2 комментария
13 938 просмотров


#1 Maratsky, 19 янв 2013 в 01:43
Сама статья и идея интересные, а вот в реализации синтаксические ошибки. strcmp()==0 когда сравниваемые строки равны, да и требует 2 значения, а у автора одно, короче, у меня заработало что-то типа
if(strcmp(md5($new_pass),$array['pass']) == 0)
echo "Пароль введен верно!";
else
echo "Пароль или логин неправильный!";
#2 freeeeez, 19 янв 2013 в 09:31
Спасибо за исправление. Там действительно ошибка. На месте $encrypt должна быть другая переменная. Исправил.

Оставить комментарий:

Имя:
Email:
Сайт:
Комментарий:

Допустимые теги: <em> • <strong> • <u> • <sub> • <sup> • <blockquote>

Проверочный код:

Введите проверочный код, для подтверждения, что вы не робот.
P.S. Если вы робот, то, к сожалению, вы
не сможете прочитать символы с картинки.