Crypt()盐生成和密码加密,执行得很好? [英] Crypt() salt generation and password encryption, well executed?

查看:468
本文介绍了Crypt()盐生成和密码加密,执行得很好?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这些是我用于密码加密和密码验证的一些功能。想知道这是否是一个很好的办法来处理它。我使用的是codeigniter框架。



这是'encrypt'的函数:

 code> function crypt_pass($ input){
$ salt = substr(sha1(date('r')),rand(0,17),22);
$ cost = 10;
$ hash ='$ 2y $'。 $ cost。 '$'。 $ salt;

$ pw_and_salt ['pw'] = crypt($ input,$ hash);
$ pw_and_salt ['salt'] = $ salt;

return $ pw_and_salt;
}

我在数据库中存储密码和盐。这里是登录函数:

  function login(){

$ this-& > select('salt');
$ salt = $ this-> db-> get_where('users',array('username'=> $ this-> input-> post('username'))) - >行();



$ where = array(
'username'=> $ this-> input-> post('username'),
'password'=> crypt($ this-> input-> post('password'),'$ 2y $ 10 $',$ salt-> salt),
);


$ user = $ this-> db-> get_where('users',$ where) - > first_row

if(!$ user){
return FALSE;
} else {
if(!empty($ user-> activation)){

return 2;

} else if($ user&& empty($ user-> activation)){
$ this-> session-> set_userdata('id',$ user - > id);
$ this-> session-> set_userdata('username',$ user-> username);
$ this-> session-> set_userdata('first_name',$ user-> first_name);

return 1;
}
}
}

办法?这是否足够的安全性?



第2版:不储存盐,从DB INSTEAD中的密码提取:

  function login(){

$ this-> db-> select('password');

$ pw = $ this-> db-> get_where('users',array('username'=> $ this-> input-> post('username')) ) - > row();


$ where = array(
'username'=> $ this-> input-> post('username'),
'password' => crypt($ this-> input-> post('password'),$ pw-> password),
);

$ user = $ this-> db-> get_where('users',$ where) - > first_row

if(!$ user){

return FALSE;

} else {

if(!empty($ user-> activation)){

return 2;

} else if($ user&& empty($ user-> activation)){

$ this-> session-> set_userdata ',$ user-> id);
$ this-> session-> set_userdata('username',$ user-> username);
$ this-> session-> set_userdata('first_name',$ user-> first_name);

return 1;
}
}
}


解决方案>

有一些要点可以改进,但首先我建议使用PHP的新功能 password_hash ()。此函数将生成安全的盐,并将其包含在生成的哈希值中,因此您可以将其存储在单个数据库字段中。对于早期版本,还存在兼容包

  //哈希一个新的密码存储在数据库中。 
//函数自动生成加密安全的盐。
$ hashToStoreInDb = password_hash($ password,PASSWORD_BCRYPT);

//检查输入的登录密码的哈希值是否与存储的哈希值相匹配。
//盐和成本因子将从$ existingHashFromDb中提取。
$ isPasswordCorrect = password_verify($ password,$ existingHashFromDb);

关于您的代码的一些想法:


  1. 您使用crypt()生成一个BCrypt哈希,因此salt将是生成的哈希的一部分。

  2. 可以改进盐的生成,使用操作系统MCRYPT_DEV_URANDOM的随机源。

  3. 如果您将成本因子更改为9,格式将无效,因为crypt期望两位数。


these are some functions I am using for password encryption and password verification. Was wondering if this is a good way to handle it. I am using the codeigniter framework.

This is the function to 'encrypt' :

function crypt_pass( $input ){
    $salt = substr(sha1(date('r')), rand(0, 17), 22);
    $cost = 10;
    $hash = '$2y$' . $cost . '$' . $salt;

    $pw_and_salt['pw'] = crypt($input, "$hash");
    $pw_and_salt['salt'] = $salt;

    return $pw_and_salt;
}

I store both the password and the salt in my DB. Here is the login function:

function login(){

    $this->db->select('salt');
    $salt = $this->db->get_where('users', array('username' => $this->input->post('username') ) )->row();



    $where = array(
        'username' => $this->input->post('username'),
        'password' => crypt( $this->input->post('password'), '$2y$10$' . $salt->salt),
    );


    $user = $this->db->get_where('users', $where)->first_row();

    if (!$user) {
        return FALSE;
    }else{
        if(!empty($user->activation)){

            return 2;

        }else if($user && empty($user->activation)){
            $this->session->set_userdata('id',$user->id);
            $this->session->set_userdata('username',$user->username);
            $this->session->set_userdata('first_name',$user->first_name);   

            return 1;
        }
    }
}

Am I implementing this the right way? Is this enough security?

VERSION 2 : NOT STORING SALT, EXTRACTING FROM PASSWORD IN DB INSTEAD :

function login(){

    $this->db->select('password');

    $pw = $this->db->get_where('users', array('username' => $this->input->post('username') ) )->row();


    $where = array(
        'username' => $this->input->post('username'),
        'password' => crypt( $this->input->post('password'), $pw->password),
    );

    $user = $this->db->get_where('users', $where)->first_row();

    if (!$user) {

        return FALSE;

    }else{

        if(!empty($user->activation)){

            return 2;

        }else if($user && empty($user->activation)){

            $this->session->set_userdata('id',$user->id);
            $this->session->set_userdata('username',$user->username);
            $this->session->set_userdata('first_name',$user->first_name);   

            return 1;
        }
    }
}

解决方案

There are some points that can be improved, but first i would recommend to use PHP's new function password_hash(). This function will generate a safe salt and includes it in the resulting hash-value, so you can store it in a single database field. There exists also a compatibility pack for earlier versions.

// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);

// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);

Some thoughts about your code:

  1. You generate a BCrypt hash with crypt(), so the salt will be part of the resulting hash. There is no need to store it separately.
  2. The generation of the salt can be improved, use the random source of the operating system MCRYPT_DEV_URANDOM.
  3. If you would change the cost factor to 9, the format would become invalid, because crypt expects two digits.

这篇关于Crypt()盐生成和密码加密,执行得很好?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆