2012-07-05 2 views
1

Хорошо, поэтому весь приведенный ниже код не является моим собственным. Я слежу за учебником в Интернете, но когда я пытаюсь запустить его, пароль не подходит. Я считаю, что может возникнуть ошибка при засовывании пароля, так как то, что находится в базе данных, нигде не находится рядом с 64 символами, описанными в скрипте login.php. Понятия не имею. Код ниже:Пароли не совпадают, когда хеширование/соление

register.php

// Create a 256 bit (64 characters) long random salt 
// Let's add 'something random' and the username 
// to the salt as well for added security 
$salt = hash('sha256', uniqid(mt_rand(), true) . 'something random' . strtolower($username)); 

// Prefix the password with the salt 
$hash = $salt . $password; 

// Hash the salted password a bunch of times 
for ($i = 0; $i < 100000; $i ++) 
{ 
    $hash = hash('sha256', $hash); 
} 

// Prefix the hash with the salt so we can find it back later 
$hash = $salt . $hash; 

// carry on with registration code... 

login.php

$email = $_POST['email']; 
$password = $_POST['password']; 

$con = mysql_connect("localhost", "redacted", "redacted", "redacted"); 

$sql = ' 
    SELECT 
     `password` 
    FROM `users` 
     WHERE `email` = "' . mysql_real_escape_string($email) . '" 
    LIMIT 1 
    ;'; 

$r = mysql_fetch_assoc(mysql_query($sql)); 

// The first 64 characters of the hash is the salt 
$salt = substr($r['password'], 0, 64); 

$hash = $salt . $password; 

// Hash the password as we did before 
for ($i = 0; $i < 100000; $i ++) 
{ 
    $hash = hash('sha256', $hash); 
} 

$hash = $salt . $hash; 

if ($hash == $r['password']) 
{ 
    session_start(); 
    header('Location: /quiz/index.php'); 
} 

if($hash != $r['password']){ 
    session_start(); 
    header('Location: /?error=4'); 
} 

// end login script 
+0

Какой учебник? У PHP есть множество дерьмовых учебников в Интернете. Кажется, это один из них. – alex

+3

Общей ошибкой является то, что поля базы данных недостаточно длинны, чтобы хранить все символы. – Konerak

+0

Ahhh ... вот почему. Поле моего пароля было всего 30 символов. Cheers @ Konerak :-) –

ответ

2

Общей ошибкой является то, что поля базы данных не хватает для хранения всех символов. Тогда пароль никогда не будет равным тому, что вводил пользователь.

Для такой функциональности всегда указывайте модульные тесты, которые проверяют, работает ли функция (по-прежнему), как ожидается. Однажды кто-то изменит базу данных, изменит хэш-алгоритм, изменит соль ... и никто не сможет войти в систему.

-1

Похоже, вы добавления соли 2 раза:

$hash = $salt . $password; 

// Hash the password as we did before 
for ($i = 0; $i < 100000; $i ++) 
{ 
    $hash = hash('sha256', $hash); 
} 

//skip the below one 
$hash = $salt . $hash; 

Update :

Действительно, в этом случае необходимо добавить соль 2 раза.

Хотя соль должна храниться в отдельной колонке db, поэтому код будет значительно упрощен - избегая всех конкатенаций строк для хранения/извлечения соли.

Кроме того, ваша структура db будет ближе к Третьей нормальной форме, сохраняя каждую информацию в отдельном слоте.

+3

Пропустите весь «хэш его много раз». Просто используйте что-то, где вы можете ввести рабочий фактор, часто рекомендуется bcrypt. – alex

+2

Вам нужно сохранить соль с помощью хэша, чтобы вы могли знать, что это такое. –

+0

Оказывается, мое поле базы данных для пароля было слишком коротким. Но спасибо за все предложения. –

Смежные вопросы