2012-05-05 74 views
0

我有一个网站,我这样做是为了让人们登录以下:笨2.1.0,jQuery的:登录安全问题

的jQuery: - 使用$ .md5()插件和$ .cookie()插件(笨CSRF保护的cookie进行后数据)

$('#login').on('submit', function(e){ 
    e.preventDefault(); 
    $.get('/salt/', function(salt){ 
    // get/set salt and salt flashdata 
    $.post('/login/', { 
     'username' : $('#l_username').val(), 
     'password' : $.md5('' + salt['m'] + $.md5($('#l_password').val()) + salt['s']), 
     //set to string (in case MD5 hash of password is an integer)hash password, add salt, hash salted password. 
     '_token' : $.cookie('_cookie') 
    }, function(r){ 
     // *r* == 0: unknown user; 1: wrong password; 2: logged in; 3: database error; 4: session error; 
     // perform action depending on *r* value 
    }) 
    }) 
}); 

PHP(笨): - 狂胜文件转发/salt//login//process/salt//process/login/ - '会话' 类自动加载

class Process extends CI_Controller { 

    public function __construct() { 
    parent::__construct(); 
    $this->load->model('login'); // loads model with login functions() 
    } 

    public function login() { 
    $data = array(); 
    $data['username'] = $this->input->post('username'); 
    $data['password'] = $this->input->post('password'); 
    if ($data['username'] && $data['password']) { 
    //if user and password are set 
     $user = $this->login->getUser($data['username']); 
     if ($user->num_rows() === 1) { 
     // if the username is in the database 
     $user = $user->row(); 
     $salt = $this->session->flashdata('s'); 
     //flashdata set by ajax call to '/salt/' 
     $pass = $salt->m . $user->password . $salt->s; 
     //password is already hashed in database 
     if ($data['password'] === $pass){ 
      // update logged_in database table then set login session 
      echo 2; // logged in; if database/session error, echo 3/4 
     } else { 
      echo 1; // wrong password 
     } 
     } else { 
     echo 0; //unknown user 
      } 
    } 
    } 

    public function salt() { 
    // set salt values based in minute and second time 
    $salt = (object) array('m' => intval(date('i')), 's' => intval(date('s'))); 
    //intval() removes leading 0 
    $this->session->set_flashdata('s', $salt); 
    // flashdata only valid for the next server request (which is the login); 
    header('Content-type: application/json'); 
    //return value as json string 
    echo json_encode($salt); 
    } 
} 

我的问题是:这种登录方法究竟有多安全?脚本中是否存在任何潜在的漏洞?我想确保登录过程尽可能安全,而无需https。

回答

0

如果我正确猜测,你是在数据库中存储密码的MD5散列版本?

用全局salt存储密码的散列并将全局salt传递给javascript会不会更好?通过这种方式,您的数据库中不会有散列,如果它是一个简单的密码,则很容易进行判定。

更好的做法是为每个用户使用一种个人用盐,您可以与其他盐同时使用。

'password' : $.md5('' + salt['m'] + $.md5($('#l_password').val() + salt['personal']) + salt['s']), 

另一个建议是使用更强的散列函数比MD5,因为这不是最安全的了。

但这都是万一你的数据库被泄露。虽然密码和用户名的转移看起来相当安全和混淆。

我认为你仍然有一个错误,因为你不会在php端比较接收到的值时在你的密码上做md5散列。我觉得应该是:

//flashdata set by ajax call to '/salt/' 
$pass = md5($salt->m . $user->password . $salt->s); 

的哈希,在服务器端,你可以使用spark-version of phpass,人人通知:使用。或者你可以把它安装成一个库。

+0

是的,我发现问题后,发现并解决了在PHP中的哈希问题。由于用户名是一个独特的元素,你认为使用它作为个人用盐可以吗?或用户ID(这是一个整数)?我一直在考虑使用SHA256而不是MD5来说实话,我只是说了MD5,以避免几个世纪以来的“散列算法”争论! –

+0

我认为userID不是一个好主意,因为这可能不会是一个很长的字符串。 [盐](http://en.wikipedia.org/wiki/Salt_(密码术))通常是较长的字符串,使它更难以[蛮力]破解(http://en.wikipedia.org/wiki/Key_stretching )。 – Zombaya

+0

另外检查出这个盐腌另一个问题:http://stackoverflow.com/questions/401656/secure-hash-and-salt-for-php-passwords – Zombaya