2010-12-16 2 views
1

У меня есть код здесь для системы входа в систему, которая является чисто или учебной целью, созданной с помощью значительной помощи великих людей stackoverflow, и мне сказали не хранить соль и хэш отдельно, а скорее вместе. Мне интересно, как я буду сравнивать пароли, когда пользователь попытается войти в систему. если соль не хранится, как я могу сравнить эти два. Может ли кто-нибудь помочь?Как сравнить пароли пользователей для входа с этим кодом?

require("constants.php"); 
$DBH = new mysqli($dbhost, $dbuser, $dbpass, $dbname); 

function createSalt() { 
    $length = mt_rand(64, 128); 
    $salt = ''; 
    for ($i = 0; $i < $length; $i++) { 
     $salt .= chr(mt_rand(33, 255)); 
    } 
    return $salt; 
} 
//Salt function created by ircmaxell 

function registerNewUser() { 
    //Check to see if  Username Is In Use// 
    $q = $DBH->prepare("SELECT id FROM users WHERE username = ?"); 
    $username = filter_var($username, FILTER_SANITIZE_STRING); 
    $data = array($username); 
    $q->execute($data); 
    $row = $q->fetch(); 

    if ($row === false) { 
     //If Username Is Not Already In Use Insert Data// 
     $hash = hash('sha256', $pass); 
     $salt = createSalt(); 
     $hash = hash('sha256', $salt . $hash . $pass); //UPDATED 
     $data = array($username, $hash, $salt); 
     $qInsert = $DBH->prepare(
      "INSERT INTO users (username, password, salt) values (?, ?, ?)" 
     ); 
     $qInsert->execute($data); //Inserts User Data Into Table// 
    } 
} 
+0

Вы можете смело пропустить строку `$ hash = hash ('sha256', $ pass);` – Jacco 2010-12-16 09:36:31

ответ

2

Вы должны опрашивать базу данных, чтобы извлечь строку пользователя (если таковые имеются), получить соль и использовать тот же алгоритм над пароль, предоставленный пользователем. Если оба хэша совпадают, пользователь предоставил хороший пароль.

делает некоторый код, что бы сделать что-то вроде этого:

$qSelect = $DBH->prepare('SELECT salt,password FROM users WHERE username = ?'); 
$qSelect->execute(); 
$qSelect->bind_result($salt, $db_password); 
$qSelect->fetch(); 

if($salt == null){ 
    // username doesn't exist 
    return; 
}  

$hash = hash('sha256', $pass); 
$hash = hash('sha256', $salt . $hash . $pass); 
if($hash == $db_password){ 
    // login ok 
} else { 
    // login nok 
} 
+0

Должен ли я хранить соль где-нибудь? Поскольку запуск кода для соли снова не приведет к таким же результатам, я не могу думать о другом способе воссоздать хэш. – mcbeav 2010-12-16 03:49:10

+0

@mcbeav: та же соль и тот же пароль должны ** всегда ** производить одинаковый хеш. – zerkms 2010-12-16 03:49:45

+0

«Хотел бы я где-нибудь хранить соль?» - вы уже сделали - вы храните его в поле «соль». – zerkms 2010-12-16 03:50:18

2

делать ту же работу:

$hash = hash('sha256', $row['salt'] . hash('sha256', $pass) . $pass); 
if ($row['password'] == $hash) { 
    // the password is correct 
} 

Где $row была взята из базы данных в соответствии с именем пользователя, и $pass является пароль, полученный из формы.

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

$hash = hash('sha256', $salt . $pass); // this would be enough 
1

Вопросы:

1) Ваш метод для создания хэш пароля хэша + соли нетрадиционный. Это не проблема, это просто не то, что казалось нужным вам. zerkms сделал это довольно ясно.

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