【问题标题】:How to campare password if it is encoded in database in CodeIgniter?如果密码在 CodeIgniter 的数据库中编码,如何比较密码?
【发布时间】:2015-06-22 17:47:32
【问题描述】:

我是数据库中 CodeIgniter 的新手,密码字段是使用加密密钥编码的,但是当我想登录时,它与密码不匹配。控制器、视图和模型的名称分别是 Hello、login 和 user_model。

这是我的观点

<html>
    <head>
        <title></title>
        <style>
            .text-danger {
                color: red;
            }
        </style>
        <script>
            function myFun() {
                var r4 = document.getElementById('email').value;
                var r5 = document.getElementById('password').value;
                if (r4 == "") {
                    document.getElementById('f4').style.display = "block";
                    return false;
                }
                else if (r5 == "") {
                    document.getElementById('f5').style.display = "block";
                    return false;
                }
            }
              function myFun4(r) {
                if (r != 0) {
                    document.getElementById('f4').style.display = "none";
                }
            }
            function myFun5(r) {
                if (r != 0) {
                    document.getElementById('f5').style.display = "none";
                }
            }
        </script>
    </head>
    <body style="background-color: #99BC99">
        <br>
        <form method="post" action="logindata">
            <table  border='1' align='center'>
                <tr>
                    <th>Email</th>
                    <td>
                        <input type="text" name="email" id="email"  onkeyup="myFun4(this.value)">
                        <span class="text-danger"><?php echo form_error('email'); ?></span>
                        <span id="f4" class="text-danger" style="display: none">This Field is required</span>
                    </td>
                </tr>
                <tr>
                    <th>Password</th>
                    <td>
                        <input type="password" name="password" id="password"  onkeyup="myFun4(this.value)">
                        <span class="text-danger"><?php echo form_error('password'); ?></span>
                        <span id="f5" class="text-danger" style="display: none">This Field is required</span>
                    </td>
                </tr>
                <tr>
                    <th colspan="2"><button id="submit" name="submit" onclick="return myFun()">Submit</button></th>
                </tr>
            </table>
        </form>
    </body>
</html>

我的控制器是

<?php
class Hello extends CI_Controller {

    public function __construct() {
        parent::__construct();
        $this->load->library('session');
        $this->load->helper('form');
        $this->load->helper('url');
        $this->load->helper('html');
        $this->load->library('image_lib');
        $this->load->database();
        $this->load->library('form_validation');
        $this->load->model('user_model');
        $this->load->library('encrypt');
    }

    function index() {
        $this->load->view('login.php');
    }

    function logindata() {
        $f1 = $this->input->post("email");
        $f2 = $this->input->post("password");
        $encrypt_pwd2 = $this->encrypt->encode($f2);
        $this->form_validation->set_rules("email", "Email", "trim|required");
        $this->form_validation->set_rules("password", "Password", "trim|required");
        if ($this->form_validation->run() == FALSE) {
            $this->load->view('login');
        } else {
            $data = $this->user_model->get_password($f1, $f2);
            $plainpassword = $this->encrypt->decode($data);
            if ($plainpassword == $f2) {
                $this->dataa['posts'] = $this->user_model->userdata($f1, $f2);
                $this->load->view('home', $this->dataa);
            } else {
                $this->load->view('home');
            }
        }
    }

} ?>

这是我的模型

<?php
class User_model extends CI_Model {

    public function __construct() {
        parent::__construct();
        $this->load->database();
        $this->load->library('encrypt');
    }

    function get_password($f1, $f2) {
        $this->db->select('password');
        $this->db->from('user_detail');
        $this->db->where('email', $f1);
        return $this->db->get()->result()->row('password');
    }

    function userdata($f1, $f2) {
        $q = $this->db->get_where('user_detail', array('email' => $f1));
        if ($q->num_rows() > 0) {
            foreach ($q->result() as $row) {
                $dataa[] = $row;
            }
            return is_array($dataa) ? $dataa : array();
        }
    }

}
?>

【问题讨论】:

    标签: php jquery html mysql codeigniter


    【解决方案1】:

    我注意到的第一件事是您正在尝试“加密”密码。 99.99% 的情况下,这是错误的做法。您想要对密码执行的操作是使用专为密码存储而设计的算法。

    PHP 实际上有一个非常有用的库,称为密码哈希 (http://php.net/password-hash)。

    当你存储密码时,你想使用 password_hash 函数。下面的代码 sn -p 显示了它是如何与密码“password1!”一起使用的

    <?php
        password_hash("password1!", PASSWORD_DEFAULT);
    ?>
    

    当它运行时,它会产生类似于

    的输出
    $2y$11$q5MkhSBtlsJcNEVsYh64a.aCluzHnGog7TQAKVmQwO9C8xb.t89F.
    

    这是您将存储在数据库中的值。

    在尝试验证密码是否正确时,可以使用 php password_verify 函数。此函数将返回一个布尔值。如果返回true,则说明用户认证成功。

    <?php
        $original_hash = SOMETHING // this is the hash you have stored in a database
                                   // in this case, it would be
                                   // $2y$11$q5MkhSBtlsJcNEVsYh64a.aCluzHnGog7TQAKVmQwO9C8xb.t89F.
    
        if (password_verify('password1!', $original_hash)) {
            echo 'Successful login'; 
            // do normal login things here
        } else {
            echo 'invalid password.';
            // return an error because they had the wrong password
        }
    ?>
    

    PHP 为您减轻了很多繁重的工作,您可以使用它来安全地处理密码。

    【讨论】:

    • 基本上,您希望确定您存储的密码哈希是否对应于新生成的哈希(它的模式),而不是检查它们是否彼此相等。
    【解决方案2】:

    如果您的密码可找回,则说明您的代码存在安全漏洞!
    像“get_password”这样的函数不应该存在。

    密码必须以某种方式加密,您唯一能做的就是检查给定的输入,一旦加密,是否与存储在数据库中的相似。 @haxim 建议使用 php 库。这可能是一个很好的解决方案 - 我不熟悉它。 Mysql has its own hashing methodology:

    MySQL 在 mysql 数据库的用户表中列出用户帐户。 每个 MySQL 帐户都可以分配一个密码,尽管 user 表 不存储明文版本的密码,而是一个哈希值 计算出来的。

    MySQL 在客户端/服务器通信的两个阶段使用密码:

    当客户端尝试连接到服务器时,会有一个初始 客户端必须提供密码的身份验证步骤 具有与存储在用户表中的哈希值匹配的哈希值 客户想要使用的帐户。

    客户端连接后就可以(如果有足够的权限的话) 设置或更改用户表中列出的帐户的密码哈希。 客户端可以通过使用 PASSWORD() 函数生成一个 密码哈希,或使用密码生成语句(CREATE USER、GRANT 或 SET PASSWORD)。

    有很多关于保护用户数据的文章。这取决于您希望您的网站有多安全。但最基本的规则是密码是不可找回的,确认有效性的方法是检查加密输入是否与数据库中存储的加密值相似。

    【讨论】:

    • Mysql 散列方法不安全,不应用于密码存储。它不使用为密码存储而设计的算法。根据我的阅读,mysql 使用原始密码的 SHA1 哈希的 SHA1 哈希。这不是存储密码哈希的安全方式,为此存在大量彩虹表。
    • 谢谢。这是否意味着您建议将加密留给后端代码,或者 MySQL 可以完成这项工作,而不是本机?例如,“SELECT users.email from users where md5("password")=users.password” - 这被认为是安全的吗?
    • 一晒,那不安全。在这种情况下,您仍然只是使用 md5 保护密码,这不利于保护密码。您想在应用程序级别进行身份验证,而不是数据库。您会执行类似“SELECT username, passhash from users where username = >”之类的操作。然后,在应用程序中,您将验证 pashhash 是否匹配。看看我上面的答案,它显示了如何做到这一点。
    猜你喜欢
    • 2015-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多