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

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

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

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

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

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

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

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


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

md5(mt_rand())

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

33
задан Exception e 7 April 2010 в 16:01
поделиться

4 ответа

rand() представляет угрозу безопасности и никогда не должен использоваться для генерации маркера безопасности: rand() против 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;
}
43
ответ дан 27 November 2019 в 18:01
поделиться

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

1
ответ дан 27 November 2019 в 18:01
поделиться

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

1
ответ дан 27 November 2019 в 18:01
поделиться

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

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

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

-1
ответ дан 27 November 2019 в 18:01
поделиться