Солить мои хэши с PHP и MySQL
Как и большинство пользователей, я просто пытаюсь найти безопасный способ хранения паролей. То, что я не нашел здесь (или, может быть, мое отсутствие понимания), - это то, как получить соленый хеш в моей базе данных и отделить соль от хешированного пароля, особенно с уникальными солями для каждого пароля при сохранении соли + пароль в одиночный столбец.
Я нахожу все эти классные способы шифрования паролей (SHA-256, но MySQL поддерживает только SHA/1 и MD5?) и другие вещи из руководства PHP, но не уверен, как хранить и извлекать пароли.
Итак, это все, что я понимаю:
SHA('$salt'.'$password') // My query sends the password and salt
// (Should the $salt be a hash itself?)
После этого я теряюсь с солями.
Получить пароль без соли легко, но соль меня смущает. Где я могу получить значение из $salt снова, особенно если он уникален и безопасен? Скрыть их в другой базе данных? Константа (кажется, небезопасно)?
EDIT: Является ли ключевая переменная в HMAC, которая должна быть солью, или это что-то еще?
Ответы
Ответ 1
Прежде всего, ваша СУБД (MySQL) не нуждается в поддержке криптографических хэшей. Вы можете сделать все это на стороне PHP, и это также то, что вы должны делать.
Если вы хотите сохранить соль и хэш в том же столбце, вам нужно их конкатенировать.
// the plaintext password
$password = (string) $_GET['password'];
// you'll want better RNG in reality
// make sure number is 4 chars long
$salt = str_pad((string) rand(1, 1000), 4, '0', STR_PAD_LEFT);
// you may want to use more measures here too
// concatenate hash with salt
$user_password = sha512($password . $salt) . $salt;
Теперь, если вы хотите подтвердить пароль, который вы делаете:
// the plaintext password
$password = (string) $_GET['password'];
// the hash from the db
$user_password = $row['user_password'];
// extract the salt
// just cut off the last 4 chars
$salt = substr($user_password, -4);
$hash = substr($user_password, 0, -4);
// verify
if (sha512($password . $salt) == $hash) {
echo 'match';
}
Возможно, вы захотите взглянуть на phpass, который также использует эту технику. Это решение хеширования PHP, которое использует соление среди других вещей.
Вы должны обязательно взглянуть на ответ на вопрос, связанный с WolfOdrade.
Ответ 2
В предыдущей статье это подробно рассмотрено:
Защищенный хэш и соль для паролей PHP
Ответ 3
Лично я рекомендую разрешить MySQL делать это с помощью встроенных функций.
Как я это делаю, это создать функцию в моем конфигурационном файле базы данных, которая возвращает строку ключа. Файл конфигурации должен находиться за пределами вашего корня сайтов, чтобы веб-сервер мог получить доступ к файлу, но не к другим. например,
function enc_key(){
return "aXfDs0DgssATa023GSEpxV";
}
Затем в вашем script используйте его с запросом sql и функциями AES_ENCRYPT и AES_DECRYPT в MySQL следующим образом:
require_once('dbconf.inc.php');
$key = enc_key();
//When creating a new user
$sql = "INSERT INTO users (username, password) VALUES ('bob', AES_ENCRYPT('{$key}', {$password}))";
//When retrieving users password
$sql = "SELECT AES_DECRYPT('{$key}', password) AS password FROM users WHERE username like 'bob'";