Уникальное текстовое поле в MySQL и php - PullRequest
5 голосов
/ 07 апреля 2010

Я создал соль, используя;md5 (RAND (0,10000000));(возможно, есть лучший способ?)

Кажется, невозможно сделать текстовое поле уникальным в MYSQL.Так как я могу проверить, использовалась ли соль для предыдущего пользователя?

Или я должен сгенерировать соль на основе текущей даты / времени?как невозможно для 2 пользователей одновременно зарегистрироваться правильно?

Ответы [ 6 ]

1 голос
/ 07 апреля 2010

Индексы MySQL ограничены по длине в текстовых полях, они не обрабатываются автоматически по всему полю, как в случае полей char / varchar, поэтому практического способа использования уникального ключа в текстовых полях нет.

Но если вы храните хеши, сгенерированные MySQL, вам не нужен текст - результаты имеют простой текст, поэтому просто используйте поле char фиксированной длины:

mysql> select length(md5('a')), length(sha1('a'));
+------------------+-------------------+
| length(md5('a')) | length(sha1('a')) |
+------------------+-------------------+
|               32 |                40 | 
+------------------+-------------------+

и тогда вы МОЖЕТЕ применить уникальное ограничение к этому полю.

1 голос
/ 07 апреля 2010

Для соли уникальность важнее, чем длина и предсказуемость. Вы предполагаете, что у атакующего есть соль.

Было бы лучше использовать универсально уникальный идентификатор (UUID), и есть примеры, которые генерируют универсально уникальные идентификаторы на странице документа для функции php uniqueid () . UUID имеет преимущество перед случайной строкой в ​​том, что она удобочитаема и имеет фиксированную длину, поэтому вы можете сохранить ее в поле varchar и использовать уникальный индекс, чтобы гарантировать отсутствие дубликатов.

Хэширование времени с помощью MD5 является распространенным методом генерации уникальных значений, поскольку он имеет фиксированную длину и удобочитаем для человека. Однако, имеет больше смысла просто генерировать случайную строку фиксированной длины и кодировать ее в шестнадцатеричный код самостоятельно. Хэши не рассчитаны на уникальность настолько, насколько они созданы, чтобы не быть обратимыми. Использование функции хеширования гарантирует коллизии, хотя коллизий с SHA1 будет меньше, чем с MD5.

Длина соли действительно является одним из факторов, потому что чем длиннее соль, тем более вероятно, что она будет универсально уникальной.

0 голосов
/ 07 апреля 2010

Вы обычно не генерируете строки соли часто. Поэтому, когда вы впервые их генерируете, вы должны делать хорошую работу. Чем длиннее и больше случайных строк, тем лучше.

function generateSalt($length = null)
{
  if (!is_int($length) || ($length < 1)) $length = 250;
  do {
    $salt[] = chr(mt_rand(0, 255));
  } while (--$length);
  return implode('', $salt);
}

запрос на обновление нового пароля

update user set salt = :salt, password = sha1(concat(:password, :salt)) where id = :id limit 1;

Вы можете проверить правильность пароля и одновременно получить данные пользователя.

select * from user where id = :id and password = sha1(concat(:password, salt)) limit 1;
0 голосов
/ 07 апреля 2010

Создайте соль с помощью SHA1 , используя идентификатор пользователя и дату и время.

0 голосов
/ 07 апреля 2010

вы можете использовать что-то вроде http://php.net/manual/en/function.uniqid.php для генерации UUID. или временная метка тоже хорошая - может быть, даже временная метка и IP-адрес или подобное.

0 голосов
/ 07 апреля 2010

md5 () - неисправный алгоритм, и его никогда не следует трогать.

rand () немного сломан, потому что он основан на системных часах.

Лучший метод:

function generateRandomKey()
{
    return base_convert(uniqid(mt_rand(), true), 16, 36);
}

Редактировать: Если есть лучший способ или я ошибаюсь, пожалуйста, покажите мне, как это сделать Я искренне заинтересован и хотел бы знать, не чувствую ли я себя в безопасности.

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