Как хеши необработанных двоичных данных должны храниться в MySQL? - PullRequest
3 голосов
/ 02 июня 2009

Я хочу хранить хешированные пароли в MySQL, я использую PHP:

<?php
    $salt = '!£$%^&*()#';
    $username = 'abc';
    $password = '123';
    $hash = hash('sha1', $username . $salt . $password, true);
?>

Истинный параметр в hash () вернет значение в виде необработанных двоичных данных. Но я не понимаю, что именно это значит. Как это должно правильно храниться в MySQL?

Ответы [ 4 ]

5 голосов
/ 02 июня 2009

Я нашел решение.

Обычные (шестнадцатеричные) хэши sha1 () всегда имеют длину CHAR (40). Когда вы возвращаете хэш в виде необработанных двоичных данных в php, он возвращает строку как CHAR (20), экономя 50% пространства базы данных, но представляя точно такое же значение. Это связано с тем, что 2 символа гекса могут быть сжаты в 1 символ, что позволяет вдвое сократить необходимое пространство.

Сохраните пароль как CHAR (20) и используйте сопоставление * _bin.

3 голосов
/ 02 июня 2009

Последний параметр функции hash () указывает, как возвращается значение хеша:

  • Либо как необработанные двоичные данные. Сюда вы получите прямой вывод конкретная хеш-функция, которую вы используете, в данном случае sha1.
  • Или как строка, содержащая шестнадцатеричное представление тех же необработанных двоичных данных.

Они оба одинаковы и отличаются только по своему представлению. Если у вас нет веских причин, я бы предложил использовать шестнадцатеричное представление и сохранить его в виде строки в вашей базе данных. Таким образом, отладка проблем будет намного проще, так как вы можете легко распечатать шестнадцатеричное хеш-значение.

1 голос
/ 02 июня 2009

Если вы хотите сохранить необработанную двоичную строку в MySQL, объявите столбец BINARY(16), если он имеет фиксированную длину 16 байтов, VARBINARY(32), если он имеет переменную длину до 32 байт или один из Типы BLOB для двоичных полей, которые потенциально могут быть очень длинными (например, BLOB до 64 КБ, LONGBLOB до 4 ГБ).

0 голосов
/ 02 июня 2009

«Нормальный» способ сделать это, AFAIK, это использовать функцию addlashes ().

например:.

$hash = hash('sha1', $username . $salt . $password, true);
$query_safe_hash = addslashes($hash);
$query_safe_username = addslashes($username);
$query = "INSERT INTO DBTable(username, password) VALUES ('$query_safe_username', '$query_safe_hash')";
mysql_query($query) or die("Failed to store credentials!");

Дополнительное примечание: с точки зрения лучших методов шифрования, соль должна иметь известную длину, генерироваться случайным образом и добавляться к вашему хешу перед сохранением в базе данных. Что-то вроде

$salt = generate_random_salt();
$query_safe_hash = addslashes($salt) . addslashes(hash('sha1', $salt . $username . $password, true);

Затем для проверки учетных данных пользователя вы извлекаете сохраненный хеш, удаляете косые черты и удаляете известную длину соли из начала сохраненного хеша и используете ту же соль для создания хеша из предоставленных учетных данных, а затем сравниваете. Это помогает защитить ваш хэш-алгоритм от различных атак криптоанализа (в частности, дифференциального криптоанализа).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...