安全的双向散列技术

时间:2016-12-19 11:32:20

标签: php sql password-encryption

我目前正在开发文档验证系统,我希望对用户的密码进行散列或加密。

所以我的问题是,我将使用的最好和最安全的双向哈希或加密方法是什么..

1 个答案:

答案 0 :(得分:2)

正如上面的评论中所建议的那样,最好和最简单的方法是使用password_hash();password_verify();在php.net网站上提供更多信息,并使用预准备语句在我的基本用户注册中使用mysqli或pdo我使用了PDO。

请注意,这只是如何使用password_hash和password_verify()的基本示例;

我们将在注册时使用password_hash()并在登录时使用password_verify()

<强> db.php中

<?php


    $server="localhost";
    $username="root";
    $password="";

    try{

        $dbh = new PDO("mysql:host=$server;dbname=sytemDb",$username,$password);
        $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    }catch(PDOException $exc){

        error_log($exc);
    }
?>

上面的脚本连接到我们的数据库。

<强> register.php

<?php

    include 'db.php';
    $errors="";
    if (isset($_POST['register'])) {

        //check if values are not empty

        if(empty($_POST['email'])){

            die("please enter email");
            $errors++;
        }else{

            $email = $_POST['email'];

            //then check for valid email
        }
    }
    if(empty($_POST['upass'])){

        die("enter password");
        $errors++;
    }else{

        $password = $_POST['upass'];

        $hash = password_hash($password,PASSWORD_DEFAULT);//hashing password
    }

    if($errors <=0){

        //no errors save to db

        $stmt= $dbh->prepare("INSERT INTO users (username,password) VALUES(?,?)");
        $stmt->execute(array($username,$hash));

        echo "User registered";
    }


?>







<!DOCTYPE html>
<html>
<head>
    <title>User Registration</title>
</head>
<body>


    <form method="POST" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">

        <input type="email" name="email" placeholder="Ente Username">
        <input type="password" name="upass" placeholder="Enter Password">
        <button type="submit" name="register">Register</button>

    </form>

</body>
</html>

<强>的login.php

<?php
    ob_start();
    session_start();

    include 'db.php';

    if(isset($_POST['login'])){


        if(empty($_POST['username']) || empty($_POST['pass'])){

            die("enter password or username");
        }else{

            $uname = $_POST['username'];
            $password = $_POST['pass'];
        }

        try {

            $stmt = $dbh->prepare("SELECT userid,password,username from users where username = ?");
            $stmt->bindValue(1,$uname);
            $stmt->execute();

            $results = $stmt->fetchall(PDO::FETCH_ASSOC);

            if(count($results) > 0){
                //if username is correct continue check entered password against saved hash

                foreach ($results as $row) {

                    if(password_verify($password,$row['password'])){
                        //password and saved hash match go to dashboard

                        echo "login success";
                        $_SESSION['user']= $row['userid'];
                        header("refresh:5;url=dashboard");
                    }else{

                        echo "username and password does not match";
                    }
                }
            }else{

                echo "username and password does not match";
            }

        } catch (PDOException $e) {


            error_log($e);

        }
    }






?>




<!DOCTYPE html>
<html>
<head>
    <title>Login</title>
</head>
<body>

<form method="POST" action="">

    <input type="text" name="username" placeholder="Enter username">
    <input type="password" name="pass" placeholder="Enter password">

    <button type="submit" name="login">Login</button>

</form>

</body>
</html>

这应该是非常基本的密码哈希,可以在手册herehere

中找到

password_verify()也可用here

请使用你应该已经完成​​的PHP 5.6或以上版本。

关于它。希望这会指出你正确的方向。

  

注意:始终验证用户的输入,不要忘记过滤和   清理输入然后准备一个语句以保存到数据库。

让用户忘记密码,有很多方法可以重置用户密码,一种基本方法是在你的数据库上有一个autho令牌列。

以下方式对初学者来说非常基础,只是为了开始你的职业生涯lol;)

<?php

function ForgetPassword()
{

    try {
        //search the user on the database
        $stmt = $dbh->prepare("SELECT email,userid,firstname,lastname from users where email = ?");
        $stmt->bindvalue($email);
        $stmt->execute();
        $results = $stmt->fetchall(PDO::FETCH_ASSOC);
        if (count($results) > 0) { //user found generate authentication token
            foreach ($results as $row):
                $userid     = base64_encode($row['userID']);
                $randomAuth = md5(uniqid(rand()));
                $dataUpdate = $dbh->prepare("UPDATE users set auth_token = ? where email = ?");
                $dataUpdate->execute(array(
                    $randomAuth,
                    $row['email']
                ));

                //send reset link to the user

                $link = "<a href=\"" . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'] . "resetpassword?id=$userid&token=$randomAuth\">Reset your password</a>";

                $header = "MIME-Version: 1.0" . "\r\n";
                $header .= "Content-type:text/html;charset=UTF-8" . "\r\n";
                $header .= 'From: <>' . "\r\n";

                $message = "<p> Hello " . $row['firstname'] . " " . $row['lastname'] . "</p>";
                $message .= "<p> You have requested to reset your password your password</p>";
                $message .= "<p>" . $link . "</p>";

                if (mail(($row['email']), "Password Reset", $message, $header)) {

                    $successMessage = "Reset link sent to the provided email address";

                } else {

                    error_log("cound not send message");
                }
            endforeach;
        } else {

            $successMessage = "Reset link sent to the provided email address";
        }
    }
    catch (PDOException $ex) {

        error_log($ex);
    }

}
?> 

然后重置密码页

<?php

function resetPassword()
{

    if (isset($_GET['code']) && isset($_GET['token'])) {

        $code  = base64_decode($_GET['code']);
        $token = $_GET['token'];

        if (isset($_POST['resetpassword'])) {

            //check empty fields

            if (empty($_POST['newpassword'])) {

                $errorMessage = "enter password";
                $errors++;
                return $errorMessage;
            } else {

                $password = $_POST['newpassword'];

                $hash = password_hash($password, PASSWORD_DEFAULT); //password encryption
            }
            if (!empty($_POST['newpassword']) && empty($_POST['confirmpassword'])) {

                $errorMessage = "Please confirm your password";
                $errors++;
                return $errorMessage();
            }

            if (!empty($_POST['confirmpassword']) && $_POST['confirmpassword'] !== $_POST['newpassword']) {

                return "Passwords does not match";
                $errors++;
            }

        }

        if ($errors <= 0) {

            try {

                $stmt = $dbh->prepare("Update users set password = ? where userID = ? AND auth_token = ?");
                $stmt->execute(array(
                    $hash,
                    $code,
                    $token
                ));

                return "Password successfully changed.. Redirecting to login page";

                $update = $dbh->prepare("UPDATE users set aut_token = NULL where userID = ? ");
                $update->bindValue(1, $code);
                $update->execute();

                header("refresh=3:url;login");

            }
            catch (PDOException $e) {

                error_log($e->getMessage());
            }

        }

    } else {
        //token code error
        return "The link have expired, please go back and request a new one";

    }


}
?>