Изменить класс пароля, crypt () и сравнение + проверка старого пароля

Итак, я пишу код в этом разделе смены пароля на моем сайте.

Обратите внимание, что мне всего несколько недель в PHP.

Вот почему я использовал md5 для шифрования паролей раньше, но я исследовал безопасность паролей и решил использовать функцию crypt () PHP для хеширования моих паролей вместо просто md5 или около того.

У меня возникла проблема с моей предыдущей функцией смены пароля, когда пользовательская сессия была прервана после сохранения нового пароля в базе данных, в результате чего пользователь вышел из системы. Старый пароль изменить сайт для справки: http://pastebin.com/hf6WhtEQ

Мой первоначальный подход был использовать session_regenerate_id() обновить сеанс, потому что казалось, что простое обновление пароля в cookie не работает.

Поначалу казалось, что этот подход сработал, но после дальнейшего тестирования стало ясно, что он бесполезен.

Поэтому я снова начал с нуля и создал следующий код.

Я еще не внедрил файл cookie, так как я до сих пор не уверен, как это сделать, и хочу убедиться, что у меня есть надежная защита паролем, прежде чем я установлю новые файлы cookie.

Теперь мой план выглядит так:

  1. Я проверяю, вошел ли пользователь в систему и является ли он владельцем учетной записи.

  2. Я хочу проверить, совпадает ли пароль в базе данных с паролем в $oldpass,

  3. Я хочу сравнить $newpass а также $repeatpassЕсли оба пароля совпадают, я хочу зашифровать $newpass с помощью crypt(),

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

Теперь мой вопрос:

  1. Почему я продолжаю получать сообщение «Этот пользователь не существует или еще не активирован, нажмите назад», даже если в заголовке явно указано имя пользователя.

  2. Как я могу привести все в порядке, где все выполняется в соответствии с моим планом. (сейчас это своего рода неупорядоченное и я не уверен, какой должен быть правильный порядок операторов if и т. д.).

change_pass.php:

    <?php

include 'check_login_status.php';

$u="";
$oldpass=md5("");
//stripping both strings of white spaces
$newpass = preg_replace('#[^a-z0-9]#i', '', $_POST['newpass']);
$repeatpass = preg_replace('#[^a-z0-9]#i', '', $_POST['repeatpass']);

//get the username from the header
if(isset($_GET["u"])){
$u = preg_replace('#[^a-z0-9]#i', '', $_GET['u']);
} else {
header("location: compare_pass.php?u=".$_SESSION["username"]);
exit();
}

// Select the member from the users table
$sql = "SELECT * FROM users WHERE username='$u' AND password='$oldpass' LIMIT 1";
$user_query = mysqli_query($db_conx, $sql);
// Now make sure that user exists in the table
$numrows = mysqli_num_rows($user_query);
if($numrows < 1){
echo "That user does not exist or is not yet activated, press back";
exit();
}

$isOwner = "no";
//check if user is logged in owner of account
if($u == $log_username && $user_ok == true){
$isOwner = "yes";
}

$passhash = "";

if (($newpass) === ($repeatpass)) {
$passhash = crypt_sha256("$newpass", "B-Pz=0%5mI~SAOcW0pMUdgKQh1_B7H6sbKAl+9~O98E9MBPrpGOtE65ro~8R");
} else {
echo "comparison failed! :(";
}

//
if (isset($_POST["submit"]) &&($isOwner == "yes") &&($user_ok == true) &&($newpass) === ($repeatpass)) {

$sql = "UPDATE users SET `password`='$passhash' WHERE username='$u' LIMIT 1";
}
?>

<h3>Create new password</h3>
<form action="" method="post">
<div>Current Password</div>
<input type="text" class="form-control" id="password" name="oldpass" >
<div>New Password</div>
<input type="text" class="form-control" id="password" name="newpass" >
<div>Repeat Password</div>
<input type="text" class="form-control" id="password" name="repeatpass" >
<br /><br />
<input type="submit" name="submit" value="Submit">
<p id="status" ></p>
</form>

check_login_status.php:

<?php
session_start();
include_once("db_conx.php");
// Files that inculde this file at the very top would NOT require
// connection to database or session_start(), be careful.
// Initialize some vars
$user_ok = false;
$log_id = "";
$log_username = "";
$log_password = "";
// User Verify function
function evalLoggedUser($conx,$id,$u,$p){
$sql = "SELECT ip FROM users WHERE id='$id' AND username='$u' AND password='$p' AND activated='1' LIMIT 1";
$query = mysqli_query($conx, $sql);
$numrows = mysqli_num_rows($query);
if($numrows > 0){
return true;
}
}
if(isset($_SESSION["userid"]) && isset($_SESSION["username"]) && isset($_SESSION["password"])) {
$log_id = preg_replace('#[^0-9]#', '', $_SESSION['userid']);
$log_username = preg_replace('#[^a-z0-9]#i', '', $_SESSION['username']);
$log_password = preg_replace('#[^a-z0-9]#i', '', $_SESSION['password']);
// Verify the user
$user_ok = evalLoggedUser($db_conx,$log_id,$log_username,$log_password);
} else if(isset($_COOKIE["id"]) && isset($_COOKIE["user"]) && isset($_COOKIE["pass"])){
$_SESSION['userid'] = preg_replace('#[^0-9]#', '', $_COOKIE['id']);
$_SESSION['username'] = preg_replace('#[^a-z0-9]#i', '', $_COOKIE['user']);
$_SESSION['password'] = preg_replace('#[^a-z0-9]#i', '', $_COOKIE['pass']);
$log_id = $_SESSION['userid'];
$log_username = $_SESSION['username'];
$log_password = $_SESSION['password'];
// Verify the user
$user_ok = evalLoggedUser($db_conx,$log_id,$log_username,$log_password);
if($user_ok == true){
// Update their lastlogin datetime field
$sql = "UPDATE users SET lastlogin=now() WHERE id='$log_id' LIMIT 1";
$query = mysqli_query($db_conx, $sql);
}
}
?>

0

Решение

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

Кроме того, на заметку, поскольку мы говорим о безопасности. Привязать ваши параметры вместо того, чтобы помещать их в свой код, вот так! Это практически исключает возможность внедрения SQL и позволяет вам не запускать регулярные выражения для всех ваших входов.

0

Другие решения

Несколько вещей происходят со мной с вашим подходом.
Во-первых, вы упоминаете шифрование пароля с использованием crypt. Это один из способов хеширования данных, а не шифрование. В php и mysql есть встроенные функции для правильного шифрования — это означает, что пароли могут быть расшифрованы, если необходимо, но сохранены надежно. Процедуры хеширования, такие как MD5, небезопасны и были взломаны, поэтому более надежный подход состоял бы в шифровании паролей с использованием шифра 256 и очень сложного ключа.

Например, в MySQL:

aes_encrypt('password','complex key') /*to encrypt*/
aes_decrypt( '<encrypted pwd>,'complex key' ) /*to decrypt*/

Второе: чтобы согласиться с Danbopes выше, bindParams практически исключает атаки SQL-инъекций, что должно быть хорошо.

В-третьих: Вы упоминаете о сохранении пароля в куки — даже в хешированной форме. Это очень плохая идея и ее следует избегать. Что если злоумышленник перехватит этот файл cookie?

Наконец — mysqli — это хорошо, но PDO, на мой взгляд, лучшая альтернатива, но это, вероятно, просто личный выбор.

0

По вопросам рекламы [email protected]