Правильно ли используется PDO и подготовленные операторы для безопасного входа? - PullRequest
2 голосов
/ 15 декабря 2010

Еще раз обращаюсь за помощью по безопасности PHP и системе входа в систему.Интересно, если я сделал это правильно здесь.Если я не был достаточно конкретен, спросите, любая помощь очень ценится.Я пытаюсь создать безопасную систему входа в систему, просто для целей обучения.вот код:

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//  
    }
}

Ответы [ 2 ]

3 голосов
/ 15 декабря 2010

Это выглядит хорошо до сих пор. У меня есть три предложения:

  1. Выберите более длинную соль
  2. Не храните соль и пароли отдельно
  3. Если ваше соединение с базой данных не localhost, используйте другой соединитель базы данных: PDO (пока) не поддерживает соединения SSL

РЕДАКТИРОВАТЬ: Кроме того, проверьте входные данные, которые клиент предоставляет как «имя пользователя». Но так как ваш пример кода - всего лишь отрывок, я думаю, вы это делаете.

РЕДАКТИРОВАТЬ # 2: Когда я сказал: «Не храните соль и пароль отдельно», я имел в виду включение соли в сохраненный хэш пароля. Поскольку выбранный вами алгоритм хеширования создает довольно длинную строку (64 символа), состоящую из [0-9a-f], вы можете подумать о создании соли произвольной длины (в данном случае это относится к ircmaxell) и либо объединить ее с началом, либо конец хэша пароля. Таким образом, вы в конечном итоге будете хранить значения бессмысленной переменной длины (96 - 128 символов) (для посторонних):

$hash = hash('sha256', $pass);
$salt = substr(hash('sha256', mt_rand(0, 1337)), mt_rand(0, 31), 32);
$hash = $salt . hash('sha256', $salt . $hash . $pass);
2 голосов
/ 15 декабря 2010

Одно предложение. Добавьте пароль в прогон подсолки:

$hash = hash('sha256', $pass);
$salt = createSalt();
$hash = hash('sha256', $salt . $hash . $pass);

Причина в том, чтобы избежать столкновений (хотя с SHA-256 это маловероятно). Допустим, есть строка foo, которая сталкивается с вашим паролем bar, когда пробег через sha256 ... $hash из первого раунда будет идентичен, поэтому второй раунд хеширования также даст идентичные результаты: *

$hash = hash('sha256', 'foo'); // "test" for example
$hash = hash('sha256', 'bar'); // "test" since it's a collision

$newHash = hash('sha256', $salt . $hash); //The same for both foo and bar!

Принимая во внимание, что если вы повторно введете пароль во втором раунде, он не будет напрямую конфликтовать, так как строка отличается для каждого раунда хэша ...

Редактировать: Что касается соления, я бы порекомендовал что-то вроде этого (кросс-платформенный):

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

Он использует символы вне нормального диапазона (намного выше), но исключает символы общего управления и пробельные символы, которые могут быть удалены базой данных (или обрезаны). Обратите внимание, что он возвращает допустимую строку ISO-8859-1 (Latin-1). Это не допустимая строка UTF-8. Поэтому убедитесь, что набор символов столбца правильный, или в худшем случае измените 255 на 127 в приведенном выше коде (но это значительно снижает прочность соли) ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...