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

Я использовал 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; } 

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

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

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

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

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

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

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

Например

 PASSWORD HASH iloveSO gjroewjgo password knbnogjwm secret gjroehghe jbieber rewgroewj 

и т.п.

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

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

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

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

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

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