Публикую и очень просто объясняю элегантное, на мой взгляд, решение проблемы хэширования и проверки пароля по хэшу.
function pass_hash($pass, $login, &$salt32) {
$salt32 = '';
$symbls = array_merge(range('A','z'),range(0,9),range('!','?'));
for ($i = 0; $i < 32; $i++) {
$salt32 .= $symbls[rand(0, 98)];
}
$salt = md5($login) . $salt32;
return hash('sha512', $salt.$pass);
}
function pass_hash_check($pass, $hash, $login, $salt32) {
return $hash == hash('sha512', md5($login) . $salt32 . $pass);
}
Легенда
Первое неписанное правило безопасности web-программиста гласит: храни хэш от пароля, а не сам пароль. С ним можно делать аутентификацию в небезопасных сетях без риска раскрыть пароль. Убедившись, что хэш — это, к сожалению, не так безопасен, как шифр, программист понимает необходимость иметь ключ («соль») к получению правильного хэша, и приходит ко второму правилу — соли пароль перед хэшированием. Новой идеей программиста становится произвольная соль: теперь пользователь сможет сменить хэш, не меняя пароля.
Как они работают
$login = 'admin';
$pass = '123qwe';
$salt32 = '';
$hash = pass_hash($pass, $login, $salt32); //$salt32 теперь вида 44K.$=o:D:/v)g:>ji?J90$X,CbX=_xm
if (pass_hash_check($pass, $hash, $login, $salt32))
echo 'OK';
Первая функция генерирует sha512 для пароля с 512-битной солью. Соль состоит из двух частей: 32 символа случайной строки из букв, цифр и спец. символов, и md5 от имени пользователя. SHA-512 функция возвращает, а в переменную $salt32 помещает первую часть соли. Эти два значения необходимо сохранить, для последующей проверки пароля.
Не намного сложнее изменить хэш, не меняя пароля:
if (pass_hash_check($pass, $hash, $login, $salt32)) {
$salt32 = '';
$hash = pass_hash($pass, $login, $salt32);
// PROFIT!
}
Автор: Vasya_Sh