Сделать mt_rand () максимально безопасным

Я пишу программу лотереи, где у людей есть билеты, которые обозначены натуральными числами в диапазоне от 1 до 100 включительно.

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

Теперь я сделал небольшое исследование и узнал из вики-статьи Merseene, что:

Наблюдая достаточное количество итераций (624 в случае MT19937, так как это размер вектора состояния, из которого производятся будущие итерации) позволяет предсказать все будущие итерации.

Используется ли текущая версия mt_rand () MT19937?

Если да, то что я могу сделать, чтобы сделать мои сгенерированные числа более криптографически безопасными?

Заранее спасибо 🙂

Короткий ответ:

Если да, то что я могу сделать, чтобы сделать мои сгенерированные числа более криптографически безопасными?

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

Когда PHP 7 выходит, вы можете использовать random_int() в своих проектах, когда необходим криптографически безопасный генератор случайных чисел.

«Хорошо, отлично, но PHP 7 еще не вышел. Что я делаю сегодня

Ну, вам повезло, у вас есть два хороших варианта.

Используйте RandomLib . ИЛИ

Я работал над backporting функциями CSPRNG PHP 7 в проектах PHP 5. Он живет на Github под paragonie / random_compat .

«Я не хочу использовать библиотеку, как мне безопасно откатываться?»

Когда дело доходит до криптографии, развертывание собственной реализации обычно является плохим решением. «Не придумано здесь», обычно это хорошо. Однако, если вы мертвы, написав свою собственную библиотеку PHP, чтобы надежно генерировать случайные целые числа или строки , нужно иметь в виду несколько вещей:

  1. Используйте надежный источник случайности. В порядке предпочтения , чтение из /dev/urandom должно быть вашим первым выбором, за которым следует mcrypt_create_iv() с MCRYPT_DEV_URANDOM , за которым следует чтение из CAPICOM (только для Windows) и, наконец, openssl_random_pseudo_bytes() .
  2. При чтении из /dev/urandom свои файловые дескрипторы, чтобы уменьшить накладные расходы для каждого вызова функции.
  3. При чтении из /dev/urandom PHP всегда будет буферизовать 8192 байта данных (что, скорее всего, вы не будете использовать). Обязательно отключите буферизацию чтения (т.е. stream_set_read_buffer($fileHandle, 0); ).
  4. Избегайте любых функций или операций, которые могут утечка информации о времени. Это означает, что вы хотите использовать побитовые операторы вместо математических функций (например, log() ) или что-либо, что связано с поплавками.
  5. Не используйте оператор modulo для уменьшения случайного целого числа до диапазона. Это приведет к смещенному распределению вероятности: Предвзятое распространение доказательство концепции
  6. Хороший CSPRNG не откажется от небезопасных результатов. Не используйте только mt_rand() если нет подходящего CSPRNG; вместо этого выкиньте неперехваченное исключение или выполните фатальную ошибку. Немедленно обратитесь к разработчику.

Извините, но Mersenne Twister не был разработан для удовлетворения криптографических требований. Нет, вы не можете и не должны пытаться это исправить, потому что обычно, когда неспециалисты пытаются улучшить криптографическую функциональность, они просто ухудшают ситуацию.

Php имеет долгую историю проблем с ее случайностью для криптографических целей. Я укажу несколько ссылок на чтение света:

  • Я забыл свой пароль: случайность атаки на PHP-приложения
  • Раскрутка PHP lcg_value ()
  • phpwn: атака на сеансах PHP и случайных числах

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

mt_rand по самому своему названию – Mersenne Twister, небезопасный генератор случайных чисел. Кроме того, он часто засевается с определенным временем в мс, что-то, что атакующий может просто угадать или стремиться.

Вы не можете защитить Мерседэн Твистер. Поэтому, если возможно, вы должны использовать защищенный генератор случайных чисел, засеянный энтропийным источником. Этот источник энтропии обычно получают из операционной системы. Предпочитаете использовать OpenSSL.

Нет абсолютно никакой причины, почему вы застряли бы с MT. PRNG – это просто алгоритмы. Существует множество библиотек, содержащих защищенные PRNG.