2015-04-19 3 views
2

Я собрал сценарий входа в систему php и, хотя мне удалось заставить страницу регистрации работать (таким образом, исключая содержимое моего файла common.php в качестве проблемы) и проверили в mySQL, который заполняется базой данных, я, похоже, не могу заставить логин публиковать что-либо другое, кроме неудачного.Ошибка входа PHP/mySQL

Я определенно набираю имя пользователя и пароль, которые находятся в базе данных. Может ли кто-нибудь увидеть, где я ошибаюсь, или посоветовать, как я буду проверять, что не так?

В таблице jmp_users имеет структуру:

jmp_userID/init(11)/auto_increment 
jmp_username/varchar(30)/utf8_unicode_ci 
jmp_password/varchar(40)/utf8_unicode_ci 
salt/char(16)/utf8_unicode_ci 

и моя страница login.php является:

<?php 

require("common.php"); 

$submitted_username = ''; 

if(!empty($_POST)) 
{ 
    $query = " 
     SELECT 
      jmp_userID, 
      jmp_username, 
      jmp_password, 
      salt 
     FROM jmp_users 
     WHERE 
      jmp_username = :username 
    "; 
    $query_params = array( 
     ':username' => $_POST['jmp_username'] 
    ); 

    try 
    { 
     $stmt = $db->prepare($query); 
     $result = $stmt->execute($query_params); 
    } 
    catch(PDOException $ex) 
    { 
     die("Failed to run query: " . $ex->getMessage()); 
    } 
    $login_ok = false; 
    $row = $stmt->fetch(); 
    if($row) 
    { 
     $check_password = hash('sha256', $_POST['jmp_password'] . $row['salt']); 
     for($round = 0; $round < 65536; $round++) 
     { 
      $check_password = hash('sha256', $check_password . $row['salt']); 
     } 

     if($check_password === $row['jmp_password']) 
     { 
      $login_ok = true; 
     } 
    } 
    if($login_ok) 
    { 
     unset($row['salt']); 
     unset($row['jmp_password']); 
     $_SESSION['user'] = $row; 
     header("Location: private.php"); 
     die("Redirecting to: private.php"); 
    } 
    else 
    { 
     print("Login Failed."); 
     $submitted_username = htmlentities($_POST['jmp_username'], ENT_QUOTES, 'UTF-8'); 
    } 
} 

?> 
<h1>Login</h1> 
<form action="login.php" method="post"> 
    Username:<br /> 
    <input type="text" name="username" value="<?php echo $submitted_username; ?>" /> 
    <br /><br /> 
Password:<br /> 
<input type="password" name="password" value="" /> 
<br /><br /> 
<input type="submit" value="Login" /> 
</form> 
<a href="register.php">Register</a> 
+1

У вас есть немного искаженная логика, когда вы генерируете хэш (ы). Форма регистра также работает с тем же процессом хэширования? BTW, вы можете использовать встроенные функции password_verify (https://php.net/manual/ro/function.password-verify.php). – Cristik

+0

Да, это так (насколько я могу судить). Я использую код из http://forums.devshed.com/php-faqs-stickies-167/program-basic-secure-login-system-using-php-mysql-891201.html, но удаленные части электронной почты поскольку они не нужны для моих целей. –

+1

ли ваш скрипт входит в 'if ($ row)' part ???? – shaN

ответ

3

, как вы используете SHA256 (с шестнадцатеричными значениями, а не сырой) вам нужно 64 символа для хранения хэша пароля (у вас всего 40).

кстати: Я думаю, что повторное хеширование пароля 65536 раз не нужно, а CPU расточительствовает. Кроме того, для всех паролей обычно используется одна сольная строка.

+1

Хеширование пароля несколько раз и использование нескольких солей намного лучше для обеспечения безопасности. – Michas

+0

Да, количество повторных хэширов было куплено из кода, который я последовал за его построением. теперь он значительно сокращен. количество доступных символов для пароля теперь исправлено, и запись базы данных для тестирования заменена, но все равно не повезло. Наверное, я слежу за устаревшим учебником. Я бы с удовольствием следил за менее устаревшим, если кто-то может указать мне на одного. –

+0

@Michas конечно. Но 65536 раз в ненужном максимуме. Что касается ** соли **, вы можете выбрать несколько солей, если вы работаете на веб-сайте «Пентагон». Но здесь у нас есть главный недостаток: соль хранится вместе с хешированным паролем. Это плохо, потому что любой, кто ломает db, видит как соль, так и хешированный пароль. Соль должна оставаться в другом месте, скорее всего, в коде. Очевидно, что все это обсуждение имеет смысл, если соединение клиент-сервер превышает ** https **, в противном случае существует еще больший недостаток, поскольку пароль отправляется через сеть. – Paolo