首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用password_hash和SHA256加密和解密

用password_hash和SHA256加密和解密
EN

Stack Overflow用户
提问于 2014-11-22 19:45:08
回答 1查看 4.1K关注 0票数 1

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

在我的注册页面上我用这个..。

代码语言:javascript
复制
        $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')";

这是我的用户登录类..。

代码语言:javascript
复制
                <?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;
                                }

                          }


                }



                ?>

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

代码语言:javascript
复制
            <?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
            }

            ?>

由于某些原因,它不会在登录时验证我的散列。我可以看到它存储了哈希,成功地解析了salt,但它不会验证?

EN

回答 1

Stack Overflow用户

发布于 2014-11-22 20:25:04

请记住,散列是一个单向函数,因此没有所谓的“解密”哈希的概念。您对密码做了一些操作(散列)并将其存储在数据库中。接下来,当需要验证用户提供的密码时,与用户提供的密码(散列或执行相同的哈希转换)执行相同的操作,然后将结果哈希与数据库中保存的哈希进行比较。如果它们匹配,那么用户必须提供了正确的密码。

在您的验证例程中,您获取的盐分如下:

代码语言:javascript
复制
$salt = substr($storedHash, 0, 64);

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

代码语言:javascript
复制
$storedHash = $salt . $password;

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

在上面的for循环之后,没有办法从$storedHash获得原始的$storedHash

您要么需要更改存储哈希和salt的方式(也可以将salt存储在数据库中),要么需要更改在$validateHash中验证用户密码的方式。

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

代码语言:javascript
复制
   $salt = $this->salt; // salt is also stored in the database 
   $validateHash = $salt . $this->password;

        for ( $i = 0; $i < 50000; $i++ )
        {
            $validateHash = hash('sha256', $validateHash);
        }
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27081717

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档