Как создавать и хранить хэши паролей с Blowfish в PHP - PullRequest
27 голосов
/ 13 февраля 2011

1) Как создать безопасные хеши паролей Blowfish с помощью crypt ()?

$hash = crypt('somePassword', '$2a$07$nGYCCmhrzjrgdcxjH$');

1a) Что означает значение «$ 2a»?Означает ли это, что следует использовать алгоритм Blowfish?
1b) Что означает значение «$ 07»?Означает ли более высокое значение более безопасный хеш?
1c) Что означает значение «$ nGYCCmhrzjrgdcxjH $»?Это соль, которая будет использоваться?Должно ли это быть случайно сгенерировано?Hard-код?

2) Как вы храните хеши Blowfish?

echo $hash;
//Output: $2a$07$nGYCCmhrzjrgdcxjH$$$$.xLJMTJxaRa12DnhpAJmKQw.NXXZHgyq

2a) Какую часть этого следует хранить в базе данных?
2b) Какие данныетип должен быть использован для столбца (MySQL)?

3) Как проверить попытку входа?

Ответы [ 2 ]

13 голосов
/ 14 февраля 2011

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

Для получения дополнительной информации см. http://www.openwall.com/articles/PHP-Users-Passwords - Я рекомендую использовать библиотеку phpass, поскольку она обрабатывает генерацию случайногосоль для вас, в отличие от crypt ().

0 голосов
/ 13 февраля 2011

1a) Прочность шифрования - требование в диапазоне 4..31.См. http://php.net/manual/en/function.crypt.php

1b) См. 1a

1c) См. 1a.'salt' не должен быть случайным, иначе вы не сможете восстановить тот же хеш для данного ввода - см. 3.

2a) Строго говоря, все, кроме хеша (в случае взлома базы данных).Кроме того, храните свою соль в файле, недоступном под корнем документа веб-сервера, и включайте его.Установите его с максимально возможными разрешениями;в идеале только для чтения веб-хостинга (например, Apache), без прав на запись или выполнение.Строго говоря, зависит от того, насколько вы хотите защититься от хакеров.Отсутствие соли только усложняет жизнь;они все еще должны правильно вводить данные в алгоритм - но зачем это проще?

2b) VARCHAR (32) должен подойти для blowfish, если не хранить хеш

3Предполагая, что вы уже выполнили правильный код для предотвращения инъекций и т.д .. , поэтому, пожалуйста, не копируйте вслепую ниже (и в идеале используйте PDO вместо расширения mysql).Ниже приведено описание только для blowfish, SHA-256 и SHA-512, которые возвращают соль в хэш.Нужна модификация для других алгоритмов ...

//store this in another file outside web directory and include it
$salt = '$2a$07$somevalidbutrandomchars$'

...

//combine username + password to give algorithm more chars to work with
$password_hash = crypt($valid_username . $valid_password, $salt)

//Anything less than 13 chars is a failure (see manual)
if (strlen($password_hash) < 13 || $password_hash == $salt)
then die('Invalid blowfish result');

//Drop the salt from beginning of the hash result. 
//Note, irrespective of number of chars provided, algorithm will always 
//use the number defined in constant CRYPT_SALT_LENGTH
$trimmed_password_hash = substring($password_hash, CRYPT_SALT_LENGTH);
mysql_query("INSERT INTO `users` (username,p assword_hash) VALUES '$valid_username', '$trimmed_password_hash'");

...

$dbRes = mysql_query("SELECT password_hash FROM `users` WHERE username = '$user_input_username' LIMIT 1");
//re-apply salt to output of database and re-run algorithm testing for match
if (substring($salt, CRYPT_SALT_LENGTH) . mysql_result($dbRes, 0, 'password_hash') ) ===
        crypt($user_input_username . $user_input_password, $salt) ) {
    //... do stuff for validated user
}
...