2010-04-07 5 views
5

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

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

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

+1

Вы можете добавить уникальное ограничение в поле varchar - вы можете использовать его для проверки дублирующих солей. – thetaiko

ответ

1

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

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

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

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

+0

должно быть какое-то уродливое совпадение. 2 пользователя, у которых одна и та же соль, решили иметь один и тот же пароль, затем –

+0

@ Джонатан, если есть дубликаты солей с разными паролями, я сначала буду атаковать эти учетные записи, так как это дает мне больше шансов при поиске успешного столкновения. Две учетные записи с одинаковой солью и паролем дадут злоумышленнику два по цене одного, но злоумышленник не получит никаких перерывов. –

0

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

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

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

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

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

+1

Для получения более широко распространенного вида см. Http://stackoverflow.com/questions/2329609/is-it-safe-to-store-passwords-hashed-with-md5cryptoserviceprovider-in-c – dkretz

+0

@ledorifier, ссылка, которую вы опубликовали о хэшировании паролей, а не генерировании случайных солей. –

+1

И http://stackoverflow.com/questions/157998/whats-the-difference-between-sha-and-md5-in-php. Я имел в виду «... никогда не прикасаться». – dkretz

0

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

0

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

1

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

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

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

и затем вы можете применить к этому полю уникальное ограничение.

0

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

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; 
Смежные вопросы