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

0

Хорошо, поэтому я кодирую эту секцию смены пароля моего сайта.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  2. Как я могу принести все в порядке, где все выполняется в соответствии с моим планом. (прямо сейчас его вид неупорядоченного и im не уверен, какой должен быть правильный порядок операторов 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
    Всем было бы действительно полезно, если бы вы немного урезали этот вопрос. Вы задаете четыре разных вопроса о трех экранах, полных кода с преамбулой, которая кажется в основном неуместной и непонятной. Так сложно получить полезные ответы. Задайте один вопрос за раз, если вообще.
  • 0
    Да, это правда, много информации для ответа, я просто подумал, что было бы лучше сохранить все, что содержится в одном посте, а не разбивать все на части и рисковать штрафом за слишком много вопросов.
Теги:
cookies
crypt

2 ответа

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 - даже в хешированной форме. Это очень плохая идея, и ее нужно избегать. Что делать, если злоумышленник перехватил этот файл cookie?

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

  • 0
    Отличный вклад! Спасибо тебе за это. Тогда вместо пароля я думаю, что я должен хранить некоторые другие данные от пользователя в куки. это действительно хороший момент. Поскольку я все еще новичок, я просто пошел с некоторыми уроками, которые использовали mysqli, и я решил выучить pdo позже, так как он намного сложнее и способен использовать все базы данных, я думал, что мне будет слишком трудно учиться как новичку.
0

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

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

  • 0
    Я подумал, что было бы лучше не извлекать пароль из базы данных по соображениям безопасности, а вместо этого сравнивать старый пароль, который будет предоставлен пользователем, с тем, который хранится в базе данных. Разве не опасно вводить пароль из базы данных в код?
  • 0
    На самом деле, нет. Они уже предоставляют свой пароль в виде открытого текста в массиве $ _POST, поэтому я не понимаю, почему извлечение зашифрованных паролей из базы данных и сравнение их через php было бы проблемой.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню