Подтвердить что ты не робот

Я правильно использую функцию PHP crypt()?

Я использую PHP crypt() как способ хранения и проверки паролей в моей базе данных. Я использую хэширование для других вещей, но crypt() для паролей. Документация не так хороша, и, похоже, много дебатов. Я использую blowfish и две соли, чтобы склеить пароль и сохранить его в базе данных. Прежде чем я сохраню соль и зашифрованный пароль (например, соленый хэш), но осознал его избыточность, потому что соль является частью зашифрованной строки пароля.

Я немного смущен тем, как атаки радужных таблиц будут работать на crypt(), в любом случае это выглядит правильно с точки зрения безопасности. Я использую вторую соль, чтобы добавить к паролю, чтобы увеличить энтропию коротких паролей, возможно, перебор, но почему бы и нет?

function crypt_password($password) {
if ($password) {
    //find the longest valid salt allowed by server
    $max_salt = CRYPT_SALT_LENGTH;

    //blowfish hashing with a salt as follows: "$2a$", a two digit cost parameter, "$", and 22 base 64
    $blowfish = '$2a$10$';

    //get the longest salt, could set to 22 crypt ignores extra data
    $salt = get_salt ( $max_salt );

    //get a second salt to strengthen password
    $salt2 = get_salt ( 30 ); //set to whatever


    //append salt2 data to the password, and crypt using salt, results in a 60 char output
    $crypt_pass = crypt ( $password . $salt2, $blowfish . $salt );

    //insert crypt pass along with salt2 into database.
    $sql = "insert into database....";

    return true;
    }
}  


function get_salt($length) {
$options = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./';

$salt = '';

for($i = 0; $i <= $length; $i ++) {
    $options = str_shuffle ( $options );
    $salt .= $options [rand ( 0, 63 )];
}
return $salt;
}

function verify_password($input_password)
{
if($input_password)
{
    //get stored crypt pass,and salt2 from the database
    $stored_password = 'somethingfromdatabase';
    $stored_salt2 = 'somethingelsefromdatabase';

    //compare the crypt of input+stored_salt2 to the stored crypt password
    if (crypt($input_password . $stored_salt2, $stored_password) == $stored_password) {
        //authenticated
        return true;
    }
    else return false;
}
else return false;
}
4b9b3361

Ответ 1

Вы действительно должны взглянуть на PHPASS: http://www.openwall.com/phpass/ Это фреймворк с использованием crypt(), который используется в таких проектах, как Wordpress и phpBB.

На этом веб-сайте также есть отличная статья о хэшировании, высыхании и растягивании паролей с помощью crypt(): http://www.openwall.com/articles/PHP-Users-Passwords

UPDATE: В настоящее время существует альтернатива для библиотеки PHPASS. В следующей версии PHP существуют специальные функции для хэширования и проверки паролей (с использованием bcrypt): http://www.php.net/manual/en/ref.password.php. Существует библиотека совместимости, которая реализует эти функции для PHP 5.3.7+: https://github.com/ircmaxell/password_compat

Ответ 2

Ваше использование crypt() в порядке. crypt($input, $stored) == $stored - это способ, которым он предназначен для использования.

Ваша функция get_salt() невелика, так как она использует часто бедную функцию rand(). Вы должны использовать более сильную случайную функцию, например openssl_random_pseudo_bytes().

Ответ 3

Идея стола радуги заключается в том, что злоумышленник может создать таблицу со всеми возможными паролями и их хешей дома.

например.

PASSWORD HASH
iloveSO  gjroewjgo
password knbnogjwm
secret   gjroehghe
jbieber  rewgroewj

и др.

С помощью этой таблицы злоумышленник может быстро преобразовать любой хеш в пароль. В таблице Rainbow используются некоторые трюки, поэтому не все хеши нужно хранить, но они все еще заранее вычисляют все хэши.

Используя соль, даже когда вы храните ее с паролем, вы делаете это намного сложнее. Вместо того, чтобы хешировать каждое слово в словаре, злоумышленнику теперь нужно будет хэшировать каждое слово с каждой солью. При наличии достаточно соли, это дает достаточно комбинаций, чтобы сделать невозможным вычисление всех этих хешей.

Таким образом, соль не должна быть дополнительным паролем, известным только приложению, он предназначен для изменения хэш-функции, так что он нестандартен.

Ответ 4

Это неправильное использование crypt(), потому что вы используете устаревший примитив. Blowfish очень старый, twofish - замена, и даже это старое, потому что три рыбки почти завершены. Вы должны использовать члена семейства sha2, sha256 или sha512 - оба хороших варианта. crypt() можно использовать с sha256 или sha512, вы должны использовать CRYPT_SHA256 CRYPT_SHA512 параметры соответственно.

Также у ваших солей очень небольшое отношение энтропии/размера, вы используете только буквенно-цифровой набор, который является шуткой, потому что алфавитно-цифровые таблицы радуги являются наиболее распространенными. Вы должны использовать полный байт, который base256, и я рекомендую соль длиной 256 байтов. Имейте в виду, что все хеш-функции являются бинарно безопасными по определению, поэтому вам не нужно беспокоиться о нулевых байтах и ​​т.п.

Ответ 5

Используйте SHA-512 (если есть) с солью, которая включает время() и openssl_random_pseudo_bytes(). Crypt является консолидированным/эффективным, потому что он возвращает соль, вставленную с хешированной строкой.