аутентификация соли - PullRequest
1 голос
/ 14 июня 2011

Спасибо за вашу честную критику в отношении моего невежества в php / mysql, и я ценю вашу помощь по этому вопросу.

После внесения предложенных ниже исправлений я столкнулся с проблемой, в которой зарегистрирован

sha1(md5($password).$salt) 

не === по сравнению с аутентификацией при входе в систему

sha1(md5($password).$row['salt']); 

Поэтому я создал сценарий, чтобы увидеть, что видит сценарий входа, и он сравнивает их.

 $query = "UPDATE `users` SET `form_password` = '$encrypted'  WHERE `username` = '$username'";  
     mysql_query($query) or die (mysql_error());

пароль зарегистрирован как "1fcb4bdeb8a98151f5f74a2af0b5045ec277c501"

и вызывается как "f2c04d2583f111fcd41288dc75901f6c870 * 101 * * * *

1015 * здесь *1014* 1015 * здесь: 1014 * * * * * * *

Ответы [ 4 ]

2 голосов
/ 14 июня 2011

Вы указали неверные идентификаторы столбцов. Используйте галочки или вообще ничего.

SELECT 'salt' FROM table WHERE ....

Вернет "соль". Используйте вместо:

SELECT `salt` ....

или

SELECT salt ....

Пожалуйста, рассмотрите также замечания, сделанные Марком Б. Все они хороши и действительны.

2 голосов
/ 14 июня 2011

а) Насколько велико ваше поле пароля в базе данных? Хеши SHA1 имеют длину 40 символов, поэтому, если у вас размер поля меньше этого, ваш хешированный пароль будет урезан.

б) Помещать or die() на линию $sql = ... бессмысленно. Создание строки чрезвычайно маловероятно, чтобы потерпеть неудачу. Вам нужно поместить or die() в строку, где фактически выполняется запрос:

$sql = "..."
$result = mysql_query($sql) or die(...);

в) Ваш код уязвим для внедрения SQL, так как вы вставляете предоставленные пользователем имя пользователя и пароль непосредственно в ваши запросы без экранирования.

d) Вы не проверяете, успешно ли выполнен запрос на получение пользователя pw / salt. Если имя пользователя неверно, запрос не будет извлекать строки. Это не условие ошибки, так как запрос сделал то, что должен был. С помощью mysql_num_rows($result) необходимо проверить, вернул ли запрос строку или нет.

1 голос
/ 14 июня 2011

я бы сделал это в псевдокоде

$salt='secretword';// that do not change
$encrypted=sha1($password.$salt);

INSERT INTO users (username,password) VALUES($username, $encrypted);

позже

//get $username and $password from user input
$encrypted=sha1($password.$salt);
SELECT * FROM users WHERE username='$username' and password='$encrypded' LIMIT 1

примечание: шифрование должно выполняться в php, потому что MySQL будет вычислять SHA1 (..) для каждой строки при сопоставлении и это ненужные траты

1 голос
/ 14 июня 2011

У вас там много неправильного.

Вот ваш рабочий код:

Пароль БД зашифрован как:

<?php
function generateSalt(){
    // Declare $salt
    $salt = '';

    // And create it with random chars
    for ($i = 0; $i < 2; $i++){
        $salt .= chr(rand(48, 57)) . chr(rand(65, 90)) . chr(rand(97, 122));
    }

    return $salt;
}
$salt       =   generateSalt();
$encrypted  =   sha1(md5($password).$salt);
$query      =   "INSERT INTO `users`(`password`, `salt`) VALUES '$encrypted', '$salt')";
?>

индекс.php

<?php
function salt() {
    // Declare $salt
    $salt = '';

    // And create it with random chars
    for ($i = 0; $i < 2; $i++){
        $salt .= chr(rand(48, 57)) . chr(rand(65, 90)) . chr(rand(97, 122));
    }

    return $salt;
 }

$password = $_POST['password'];
$username = mysql_real_escape_string($_POST['username']); 

$sql        =   "SELECT `password`, `salt` FROM `users` WHERE `username` = '$username' LIMIT 0,1";
$result     =   mysql_query($sql) or die('Could not access user.');
if(is_resource($result) && mysql_num_rows($result) > 0){
    $row        =   mysql_fetch_array($result);
    $encrypted  =   sha1(md5($password).$row['salt']);

    if($encrypted === $row['password']){
        header('Location: page3.php');
        exit;
    } else{
        header('Location: page2.php');
        exit;
    }
} else{
    header('Location: page2.php');
    exit;
}
?>
...