Если вы разрабатываете вебсайты которые требуют регистрации пользователей - ваша обязанность заключаеться в безопасном сохраниении паролей пользователей. И если вы храните пароли в открытом виде - вы не делаете свою работу качественно. Можно согласиться, что хранить пароли в открытом виде удобно, но что делать если важу базу данных с паролями украли? Это означает что можно получить доступ к данным пользователей не только на вашем сайте, но и на других так как большинство пользователей используют одинаковые пароли.
Никакие данные не могут быть безопасными если кто-либо еще имеет доступ к веб серверу (например хостинговая компания, занимающаяся размещением вашего сайта в сети интернет) или базе данных (хостинговая компания регулярнос создает резервные копии данных) тогда вы не имеете полного контроля над безопасностью хранения конфиденциальных данных. В общем всегда есть вероятность что ваша база данных может быть украденна, поэтому существует простое правило - шифруйте пароли.
Хеш - это строковые данные получаемые из оригинального пароля с помощью одностороннего алгоритма. Другими словами достаточно легко получить хеш из оригинала, но гораздо труднее (при определенных условиях практически не возможно) получить оригинал из хеша. Вы храните хеш в базе данных и когда пользователь авторизуется в системе просто сравниваете его с хешем полученным от введенного пользователем пароля. Например так:
if( $user->passwordhash == sha1( $_POST['password'] ) )
Таким образом вы никогда не будете хранить настоящие пароли пользователей.
Сушествует несколько алгоритмов хеширования в PHP среди которых md5 и sha1 наиболее распространенные. К сожалению они не настолько безопасны, как ожидалось. Будет лучше использовать более безопасный метод хеширования, и если у вас есть расширение Hash для PHP (поумолчанию с версии 5.2.1) то вы будете иметь доступ к более широкому кругу алгоритмов. Более лучший пример будет выглятеть так:
Радужная таблицаif( $user->passwordhash == hash( 'whirlpool', $_POST['password'] ) )
Но существует другая проблема. После того, как ваша база данных украденна, злоумышленник имеет достаточно времени чтобы взломать пароли используя радужные таблицы. Это выглядит прмерно следующим образом: создается большой набор хеш сумм на основе какого либо набора слов и затем полученные хеш суммы в разных комбинациях сравниваються с имеющимися в бд хеш суммами. И через час или около того примерно поливина всех ваших паролей будет расшифрованна.
Чтобы избежать этого вам стоит модифицировать пароли добавляя к ним случайную строку ( называемую salt или nonce). Основную часть времени расшивровки паролей с помощью радужных таблиц составляет построения набора хеш сумм. Добавление случайной строки к паролю повлечет за собой переформирование словарей хеш сумм с учетом случайной строки, что приведет к большим затратам времени. Каждый пароль должен иметь уникальную случайную строку.
РешениеДля обеспечения повышенной безопасности вам нужен код аналогичный следующему:
// Получим случайную строку
function getPasswordSalt()
{
return substr( str_pad( dechex( mt_rand() ), 8, '0', STR_PAD_LEFT ), -8 );
}
// Вычислим хеш
function getPasswordHash( $salt, $password )
{
return $salt . ( hash( 'whirlpool', $salt . $password ) );
}
// Сравниваем палоь и хранимый хеш
function comparePassword( $password, $hash )
{
$salt = substr( $hash, 0, 8 );
return $hash == getPasswordHash( $salt, $password );
}
// Получим хеш для пароля
$hash = getPasswordHash( getPasswordSalt(), $password );
Вам не обязательно добавлять строку к хеш сумме и вы можете хранить их раздельно. Так же строка не обязательно должна быть в шеснадцатиричном виде. Итак вы не будете иметь самый быстрый алгоритм шифрования, но будете иметь более безопасный.