Как и большинство пользователей, я просто пытаюсь найти безопасный способ хранения паролей. То, что я не нашел здесь (или, может быть, это мое отсутствие понимания), заключается в том, как получить соленый хеш в моей базе данных и отделить соль от хешированного пароля, особенно с уникальными солями для каждого пароля при сохранении соли + пароля в один столбец.
Я нахожу все эти классные способы шифрования паролей (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, которая должна быть солью, или это что-то еще?
Прежде всего, ваша СУБД (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.
В предыдущем посте это подробно рассмотрено: Безопасный хеш и соль для паролей PHP
Лично я рекомендую разрешить MySQL делать это с помощью встроенных функций.
Они делают это, чтобы создать функцию в моем конфигурационном файле базы данных, которая возвращает строку ключа. Файл конфигурации должен находиться за пределами вашего корня сайтов, чтобы веб-сервер мог получить доступ к файлу, но не к другим. так например:
function enc_key(){ return "aXfDs0DgssATa023GSEpxV"; }
Затем в вашем скрипте используйте его с 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'";