Intereting Posts
Что означает ошибка «PHP Fatal error: не может вызвать перегруженную функцию для не-объекта»? Исключение SoapFault: Неподдерживаемый тип носителя при доступе к веб-сервису Java с PHP Добавление динамического предложения where в запрос с разбиением на страницы в Laravel Почему двойной символ подчеркивания (__) в php? Как Doctrine 2 извлекает объекты без вызова конструктора объекта? Сообщение WordPress XML-RPC для определенной категории Reddit api sdk ничего не делает, возвращает null Аутентификация пользователей в WordPress с помощью wp_set_auth_cookie CMS на основе CodeIgniter Объединение двух многомерных массивов с использованием общего значения массива Расширение пользовательского класса валидации Хорошо ли иметь BaseController и заставить все контроллеры расширять этот класс? очистка экрана в php-проблеме Получите отметку времени сегодня и вчера в php mysql (почти) полный аудит

PHP хранит пароль с blowfish & salt & pepper

Я хочу хранить защищенные пароли пользователей в базе данных MySQL с помощью PHP.

Как я могу сделать это лучше?

Мои занятия:

private static $algo = '$2a'; private static $cost = '$10'; private static $pepper = 'eMI8MHpEByw/M4c9o7sN3d'; public static function generateSalt($length) { $randomBinaryString = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); $randomEncodedString = str_replace('+', '.', base64_encode($randomBinaryString)); return substr($randomEncodedString, 0, $length); } public static function generateHash($password) { if (!defined('CRYPT_BLOWFISH')) die('The CRYPT_BLOWFISH algorithm is required (PHP 5.3).'); $password = hash_hmac('sha256', $password, self::$pepper, false); return crypt($password, self::$algo . self::$cost . '$' . self::generateSalt(22)); } public static function checkPassword($hash, $password) { $salt = substr($hash, 0, 29); $password = hash_hmac('sha256', $password, self::$pepper, false); $new_hash = crypt($password, $salt); return ($hash == $new_hash); } 

Используйте либо предложения этого ответа (для PHP> = 5.5), либо следующий класс. Благодаря martinstoeckli для указания функций password_hash . Я прочитал код, и в DEV_URANDOM password_hash которое я вижу, только разные вещи, это проверка ошибок и использование DEV_URANDOM из ОС для генерации более случайной соли.

 class PassHash { public static function rand_str($length) { $chars = "0123456789./qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"; //only allowed chars in the blowfish salt. $size = strlen($chars); $str = ""; for ($i = 0; $i < $length; $i++) $str .= $chars[rand(0, $size - 1)]; // hello zend and C. return $str; } public static function hash($input) { return crypt($input, "$2y$13$" . self::rand_str(22)); // 2y is an exploit fix, and an improvement over 2a. Only available in 5.4.0+ } public static function hash_weak($input) { return crypt($input, "$2a$13$" . self::rand_str(22)); } // legacy support, Add exception handling and fall back to <= 5.3.0 public static function compare($input, $hash) { return (crypt($input, $hash) === $hash); } } 

Это то, что я всегда использовал. Предложение также является PHPass . Он проверен и проверен.


Единственным недостатком этого скрипта является то, что я генерирую случайные числа из rand() , а не источник из ОС, но это легко изменить.

Кроме того, нет реальной причины использовать SHA256 хеширование поверх bcrypt. SHA256 слаб и может быть сломан с относительно небольшим усилием 3 .

Кроме того, хеширование паролей является существенной практикой, но для истинной безопасности запустите все входные данные, по крайней мере, из словаря John the Ripper 1, чтобы удалить наиболее распространенные пароли и сообщить пользователю использовать другой пароль. Wordlists используются гораздо эффективнее, чем любая грубая сила из-за ужасно слабых паролей.


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

Длина – это все (без юмора), когда речь заходит о грубых паролях. Практически любой предустановленный взломщик будет настроен не на 12 символов, если не будет отредактирован конфиг. Если вы когда-либо видели сайт с «максимальной длиной» на паролях, не забудьте никогда не использовать там пароль, потому что у них нет никакой безопасности 4 .


1. Произвольный выбор крекера; выберите то, что вы найдете, чтобы работать лучше всего
2. http://xkcd.com/936/
3. Сравнительно (он на несколько порядков быстрее и технически защищен через неясность)
4. Я даже видел, как банки это делают. Имея максимальную длину в своих паролях, я переключил банки.