Конвертировать старые пароли md5 в password_hash - PullRequest
0 голосов
/ 08 июня 2019

Возникли проблемы при обновлении старых паролей md5 до password_hash на php-сайте. Я смог обновить все файлы до password_hash. Я просто застрял при обновлении старых паролей в базе данных, когда следующий член входит в систему

здесь, оригинальный код

    $password = passhash($_POST["password"]);

    if (!empty($_POST["username"]) && !empty($_POST["password"])) {
        $res = SQL_Query_exec("SELECT id, password, secret, status, enabled FROM users WHERE username = " . sqlesc($_POST["username"]) . "");
        $row = mysqli_fetch_assoc($res);

        if ( ! $row || $row["password"] != $password )
            $message = T_("LOGIN_INCORRECT");
        elseif ($row["status"] == "pending")
            $message = T_("ACCOUNT_PENDING");
        elseif ($row["enabled"] == "no")
            $message = T_("ACCOUNT_DISABLED");
    } else
        $message = T_("NO_EMPTY_FIELDS");

вот с password_hash

    $password = $_POST["password"];

    if (!empty($_POST["username"]) && !empty($_POST["password"])) {
        $res = SQL_Query_exec("SELECT id, password, secret, status, enabled FROM users WHERE username = " . sqlesc($_POST["username"]) . "");
        $row = mysqli_fetch_assoc($res);

        if ( !$row || !password_verify($password,$row["password"]))
            $message = T_("LOGIN_INCORRECT");
        elseif ($row["status"] == "pending")
            $message = T_("ACCOUNT_PENDING");
        elseif ($row["enabled"] == "no")
            $message = T_("ACCOUNT_DISABLED");
    } else
        $message = T_("NO_EMPTY_FIELDS");

Я думаю, что это должно быть что-то вроде этого, но не могу заставить его работать как раз перед строкой проверки

   if (strlen($password) > 40)
   {
   // Password already converted, verify using password_verify
   } else {

// User still using the old MD5, update it!
    if ($password = passhash($_POST["password"]))
    {
    // update to password_hash
    SQL_Query_exec("UPDATE users SET password WHERE username = " . 
    sqlesc($_POST["username"]) . "");
    }
}

Ответы [ 2 ]

4 голосов
/ 08 июня 2019

Я бы посоветовал вам пока сохранить старый password в базе данных и создать новый, более правильно названный, passwordHash рядом с ним.Таким образом, вы всегда можете вернуться к старому способу действий, если допустите ошибку.

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

$password = $_POST["password"];
$passwordHash = password_hash($password, PASSWORD_DEFAULT);

После этого вам необходимо сохранить новый хеш:

SQL_Query_exec("UPDATE users 
                SET passwordHash = " . sqlesc($passwordHash) . "
                WHERE username = " . sqlesc($_POST["username"]));

Использование нового хешатогда просто вопрос проверки наличия нового хеша или нет.Если это не так, вы создаете его, в противном случае вы его используете.

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

Примечание: Вы избегаете ввода пользователя вместо использования подготовленных операторов.Это не лучший вариант.См .: Как предотвратить уязвимости SQL-инъекций в приложениях PHP , где говорится:

Не очищайте ввод данных пользователем, экранируя или удаляя специальные символы.Злоумышленник может использовать кодирование, чтобы обойти такую ​​защиту.

Или заглянуть в само руководство по PHP , где написано:

Использовать подготовленные операторы с привязкойпеременные.

0 голосов
/ 08 июня 2019

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

if (!empty($_POST["username"]) && !empty($_POST["password"]))
{
    $password = $_POST["password"];
    $res = SQL_Query_exec("SELECT id, password, secret, status, enabled FROM users WHERE username = " . sqlesc($_POST["username"]) . "");
    $row = mysqli_fetch_assoc($res);
    if(strlen($row["password"]) == 40) // New hash
    {
        if ( !$row || !password_verify($password,$row["password"]))
            $message = T_("LOGIN_INCORRECT");
        elseif ($row["status"] == "pending")
            $message = T_("ACCOUNT_PENDING");
        elseif ($row["enabled"] == "no")
            $message = T_("ACCOUNT_DISABLED");
    }
    else                                // Old hash
    {
        $doUpdate = 1;
        $oldhash = passhash($password);
        if ( ! $row || $row["password"] != $oldhash )
        {
            $doUpdate = 0;
            $message = T_("LOGIN_INCORRECT");
        }
        elseif ($row["status"] == "pending")
            $message = T_("ACCOUNT_PENDING");
        elseif ($row["enabled"] == "no")
            $message = T_("ACCOUNT_DISABLED");
        if($doUpdate == 1) // Assuming all went well
                SQL_Query_exec("UPDATE users SET password = '" . newpasshashfunction($password) . "' WHERE username = " . sqlesc($_POST["username"]) . "");
    }
}
else
    $message = T_("NO_EMPTY_FIELDS");

Этот код можно немного убрать

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