md5 (uniqid) имеет смысл для случайных уникальных токенов?

Я хочу создать генератор токенов, который генерирует токены, которые не могут быть догаданы пользователем и которые по-прежнему уникальны (используются для сброса пароля и кодов подтверждения).

Я часто вижу этот код; имеет ли это смысл?

md5(uniqid(rand(), true)); 

Согласно комментарию uniqid($prefix, $moreEntopy = true) дает

первые 8 шестнадцатеричных символов = Unixtime, последние 5 шестнадцатеричных символов = микросекунды.

Я не знаю, как обрабатывается параметр $prefix -parameter.

Поэтому, если вы не устанавливаете флаг $ moreEntopy в true, это дает предсказуемый результат.


ВОПРОС: Но если мы используем uniqid с $moreEntopy , что $moreEntopy его с md5, купите нас? Это лучше, чем:

 md5(mt_rand()) 

edit1: Я буду хранить этот токен в столбце базы данных с уникальным индексом, поэтому я буду определять столбцы. Может представлять интерес /

Related of "md5 (uniqid) имеет смысл для случайных уникальных токенов?"

rand () является угрозой безопасности и никогда не должен использоваться для создания токена безопасности: rand () vs mt_rand () (Посмотрите на «статические» изображения). Но ни один из этих методов генерации случайных чисел не криптографически защищен. Для создания защищенных приложений приложение должно получить доступ к CSPRNG, предоставляемому платформой, операционной системой или аппаратным модулем.

В веб-приложении хорошим источником безопасных секретов является неблокирующий доступ к энтропийному пулу, например /dev/urandom . Начиная с PHP 5.3, приложения PHP могут использовать openssl_random_pseudo_bytes() , а библиотека Openssl выберет лучший источник энтропии на основе вашей операционной системы, в Linux это означает, что приложение будет использовать /dev/urandom . Этот код от Скотта довольно хорош :

 function crypto_rand_secure($min, $max) { $range = $max - $min; if ($range < 0) return $min; // not so random... $log = log($range, 2); $bytes = (int) ($log / 8) + 1; // length in bytes $bits = (int) $log + 1; // length in bits $filter = (int) (1 << $bits) - 1; // set all lower bits to 1 do { $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes))); $rnd = $rnd & $filter; // discard irrelevant bits } while ($rnd >= $range); return $min + $rnd; } function getToken($length=32){ $token = ""; $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz"; $codeAlphabet.= "0123456789"; for($i=0;$i<$length;$i++){ $token .= $codeAlphabet[crypto_rand_secure(0,strlen($codeAlphabet))]; } return $token; } 

Это копия другого вопроса, который я нашел, который был задан за несколько месяцев до этого. Вот ссылка на вопрос и мой ответ: https://stackoverflow.com/a/13733588/1698153 .

Я не согласен с принятым ответом. Согласно собственному веб-сайту PHP, "[uniqid] does not generate cryptographically secure tokens, in fact without being passed any additional parameters the return value is little different from microtime(). If you need to generate cryptographically secure tokens use openssl_random_pseudo_bytes()."

Я не думаю, что ответ может быть более ясным, чем этот, uniqid небезопасен.

Я знаю, что вопрос старый, но он появляется в Google, поэтому …

Как говорили другие, rand() , mt_rand() или uniqid() не гарантируют вам уникальности … даже openssl_random_pseudo_bytes() не следует использовать, поскольку он использует устаревшие функции OpenSSL .

То, что вы должны использовать для генерации случайного хэша (то же, что и md5), является random_bytes () (введено в PHP7). Чтобы генерировать хэш с такой же длиной, как MD5:

bin2hex(random_bytes(16));

Если вы используете PHP 5.x, вы можете получить эту функцию, включив библиотеку random_compat .

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

Чтобы ответить на ваш вопрос, проблема в том, что у вас не может быть генератора, который гарантирован случайным и уникальным как случайный сам по себе, т. md5(mt_rand()) может привести к дублированию. То, что вам нужно, это «случайные появления» уникальных значений. uniqid дает уникальный id, rand () прикрепляет случайное число, что делает его еще труднее догадаться, md5 маскирует результат, чтобы сделать его еще сложнее угадать. Ничего нет. Нам просто нужно сделать так, чтобы они даже не захотели попробовать.

Несколько лет назад я столкнулся с интересной идеей.
Сохранение двух значений хеширования в дате, один из которых генерируется с помощью md5 ($ a), а другой – с помощью sha ($ a). Затем произнесите chek, если оба значения являются corect. Дело в том, что если злоумышленник сломал ваш md5 (), он не сможет разбить ваш md5 и sha в ближайшем будущем.
Проблема заключается в следующем: как можно использовать эту концепцию для генерации токена, необходимой для вашей проблемы?

MD5 – достойный алгоритм для создания зависимых от данных идентификаторов. Но в случае, если у вас есть более одного элемента, который имеет тот же бит-поток (контент), вы будете создавать две аналогичные MD5-идентификаторы.

Поэтому, если вы просто применяете его к функции rand() , которая гарантированно не будет создавать один и тот же номер дважды, вы вполне безопасны.

Но для более сильного распределения ключей я лично использовал SHA1 или SHAx и т. Д. … но у вас все еще будет проблема с подобными данными, приводящими к подобным ключам.