2013-12-04 2 views
4

Это некоторые функции, которые я использую для шифрования паролей и проверки пароля. Было интересно, если это хороший способ справиться с этим. Я использую frameworkignign framework.Crypt() генерация соли и шифрование паролей, хорошо выполнены?

Это функция «шифровать»:

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->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; 
     } 
    } 
} 

Я реализую это правильно? Это достаточная безопасность?

версия 2: НЕ ХРАНЕНИЕ СОЛИ, ИЗВЛЕЧЕНИЕ ИЗ ПАРОЛЯ В БДЕ ВМЕСТО:

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; 
     } 
    } 
} 
+1

Я думаю, что этот вопрос будет лучше на стеке [code review] (http://codereview.stackexchange.com/). –

+0

См. Также раздел [PHP-хеширование PHP] (http://www.openwall.com/phpass/) (PHPass). Он переносится и затвердевает от ряда распространенных атак на пароли пользователей. Парень, который написал фреймворк (SolarDesigner), тот же парень, который написал [John The Ripper] (http://www.openwall.com/john/) и сидит в качестве судьи в [HHH] (http: /password-hashing.net/). Поэтому он знает кое-что об атаках на пароли. – jww

+0

Этот вопрос относится к другому сайту в сети Stack Exchange. Возможно, вам стоит попробовать [Code Review Stack Exchange] (http://codereview.stackexchange.com/). – jww

ответ

5

Есть некоторые моменты, которые могут быть улучшены, но сначала я бы рекомендовал использовать новую функцию РНР password_hash(). Эта функция генерирует безопасную соль и включает ее в полученное значение хеша, поэтому вы можете сохранить ее в одном поле базы данных. Существует также compatibility pack для более ранних версий.

// 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); 

Некоторые мысли о вашем коде:

  1. Вы генерировать BCrypt хэш с склепа(), так что соль будет частью полученного хэша. Нет необходимости хранить его отдельно.
  2. Генерация соли может быть улучшена, используйте случайный источник операционной системы MCRYPT_DEV_URANDOM.
  3. Если вы измените коэффициент стоимости на 9, формат станет недействительным, потому что крипт ожидает две цифры.
+0

Привет, Мартин, спасибо за ваш вклад. Я обязательно буду использовать ваши предложения. Один вопрос о текущей настройке, если я не ошибаюсь, я могу только проверить введенный пароль, хэшируя его так же, как я испортил пароль, хранящийся в БД, как я могу это сделать без актаального хранения и извлечения соли? – Jursels

+0

Я добавил свой подход для валидации без соли от БД к исходному сообщению. – Jursels

+0

@Jursels - соль уже включена в итоговое значение хэша, а функция password_verify() будет извлекать ее оттуда вместе с коэффициентом затрат. Пример: хеш-значение '$ 2y $ 10 $ nOUIs5kJ7naTuTFkBy1veuK0kSxUFXfuaOKdOKf9xYT0KKIGSJwFa' содержит соль после третьего' $ ', соль -' nOUIs5kJ7naTuTFkBy1veu'. – martinstoeckli