Соление моих хэшей с помощью PHP и MySQL - PullRequest
10 голосов
/ 18 июля 2010

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

Я нахожу все эти классные способы шифрования паролей (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 является соль или это что-то еще?

Ответы [ 3 ]

5 голосов
/ 18 июля 2010

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

3 голосов
/ 18 июля 2010

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

0 голосов
/ 18 июля 2010

Лично я рекомендую разрешить 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'";
...