使用password_hash和SHA256加密和解密

时间:2014-11-22 19:45:09

标签: php security encryption hash

我有两个脚本,一个是verify.php和一个register.php。

在我的注册页面上,我使用了这个..

        $salt = hash('sha256', uniqid(mt_rand(), true) . $email);
        $storedHash = $salt . $password;

        for ( $i = 0; $i < 50000; $i ++ )
        {
            $storedHash = hash('sha256', $storedHash);
        }


        $sql = "INSERT INTO authentication (email, password, fname, lname, created_at) VALUES ('$email', '$storedHash', '$fname', '$lname', '$today')";

这是我的用户登录类..

                <?php
                include 'dbinclude.php';



                // Class User
                class user {
                    var $username;
                    var $password;
                    var $hashed;
                    var $salt;
                    function loginUser() {
                                require 'dbinclude.php';
                                $sql = "SELECT * FROM authentication WHERE email='" . $this->username . "';";
                                $query = mysqli_query($conn,$sql);
                                $fetch = mysqli_fetch_assoc($query);
                                $id = $fetch['userid'];
                                $storedHash = $fetch['password'];

                                $salt = substr($storedHash, 0, 64);
                                $validateHash = $salt . $this->password;
                                $validateHash = hash('sha256', $validateHash);
                                if ($storedHash == $validateHash)
                                {
                                //The entered password is correct.
                                     $user = array(
                                        "status" => "allow",
                                        "email" => $fetch['email'],
                                        "fname" => $fetch['fname'],
                                        "lname" => $fetch['lname'],
                                        "id" => $id,
                                        "setupacc" => $fetch['setupacc'],
                                        "setupleads" => $fetch['setupleads'],
                                        "setupclients" => $fetch['setupclients'],
                                         "hash" => $storedHash,
                                         "salt" => $salt
                                    );  
                                    return $user;
                                }
                                else
                                { 
                                //The entered password is incorrect.
                             $user = array(
                                            "status" => "deny",
                                            "email" => $fetch['email'],
                                            "fname" => $fetch['fname'],
                                            "lname" => $fetch['lname'],
                                            "id" => $id,
                                            "setupacc" => $fetch['setupacc'],
                                            "setupleads" => $fetch['setupleads'],
                                            "setupclients" => $fetch['setupclients'],
                                            "hash" => $storedHash,
                                            "salt" => $salt
                                        );
                                        return $user;
                                }

                          }


                }



                ?>

在我的登录页面上,我使用以下代码..

            <?php
            session_start();
            require 'includes/dbinclude.php';
            require 'includes/class.user.php';
            $email = mysqli_real_escape_string($conn, $_POST['email']);
            $password = mysqli_real_escape_string($conn, $_POST['password']);




            // New login object? or class..
            $login = new user();
            $login->username = $email;
            $login->password = $password;
            $loginstatus = $login->loginUser();

            $status = $loginstatus['status'];
            $fname = $loginstatus['fname'];
            $lname = $loginstatus['lname'];
            $id = $loginstatus['id'];
            $email = $loginstatus['email'];
            $setupacc = $loginstatus['setupacc'];
            $setupleads = $loginstatus['setupleads'];
            $setupclients = $loginstatus['setupclients'];

            // Set User Info in Session
            $_SESSION['email'] = $email;
            $_SESSION['fname'] = $fname;
            $_SESSION['lname'] = $lname;
            $_SESSION['id'] =  $id;
            $_SESSION['setupacc'] = $setupacc;
            $_SESSION['setupleads'] = $setupleads;
            $_SESSION['setupclients'] = $setupclients;


            // Debug Display
            echo "Class Pass: " . $login->password;
            echo "Salt: " . $loginstatus['salt'];
            echo "Hashed: " . $loginstatus['hash'];

            if($status == "denied") {

            ?>
            <script>
            location.replace("http://hashed.com/?alertstatus=notauthed");
            </script>
            <?php

            } elseif($status == "allow") {


            ?>
            <script>
            location.replace("http://hashed.com/app.php");
            </script>
            <?php


            } else {

            ?>
            <script>
            location.replace("http://hashed.com/?alertstatus=notauthed");
            </script>

            <?php
            }

            ?>

出于某种原因,它不会在登录时验证我的哈希值。我可以看到它存储哈希,成功解析盐但它不会验证?

1 个答案:

答案 0 :(得分:3)

请记住,散列是一种单向函数,所以没有一种叫做“解密”的概念。哈希。您对密码执行某些操作(哈希)并将其存储在数据库中。接下来,当您需要验证用户提供的密码时,对用户提供的密码执行相同的操作(哈希或执行相同的哈希转换),然后将生成的哈希值与您的密码进行比较。 ;已保存在数据库中。如果匹配,则用户必须提供正确的密码。

在验证例程中,您将获取盐:

$salt = substr($storedHash, 0, 64);

但是在创建$ storedHash时,您已经损坏了并丢失了原始的盐:

$storedHash = $salt . $password;

for ( $i = 0; $i < 50000; $i++ )
{
  $storedHash = hash('sha256', $storedHash);
}

在上述for循环之后,无法从$salt获取原始$storedHash

您需要更改存储哈希值和盐的方式(将盐存储在数据库中),或者您需要更改验证用户的方式&#39 ; $validateHash中的密码。

当您对最初的$salt + $password进行哈希扫描50,000次时,您还需要在用户提供密码时再次执行相同操作,因此您的$ validateHash应如下所示:

   $salt = $this->salt; // salt is also stored in the database 
   $validateHash = $salt . $this->password;

        for ( $i = 0; $i < 50000; $i++ )
        {
            $validateHash = hash('sha256', $validateHash);
        }