Соление моих хешей с PHP и MySQL

Как большинство пользователей, я просто пытаюсь выяснить безопасный способ сохранить пароли. То, что я не нашел здесь (или возможно это - мое отсутствие понимания), - то, как получить соленый хеш в моей базе данных и разделить соль от хешированного пароля, особенно с уникальными солями к каждому паролю при поддержании salt+password в отдельном столбце.

Я нахожу все эти прохладные способы зашифровать пароли (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 снова, особенно если это уникально и безопасно? Я скрываю их в другой базе данных? Постоянный (кажется небезопасным)?

Править: Действительно ли ключ является переменным в HMAC, который, как предполагают, был солью, или является этим что-то еще?

10
задан Tarik 18 July 2010 в 01:31
поделиться

3 ответа

Прежде всего, ваша СУБД (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.

5
ответ дан 4 December 2019 в 02:25
поделиться

Кажется, это было подробно рассмотрено в предыдущем посте: Безопасный хэш и соль для паролей PHP

3
ответ дан 4 December 2019 в 02:25
поделиться

Лично я рекомендую позволить 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'";
0
ответ дан 4 December 2019 в 02:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: