Я использую PHP для написания программного обеспечения, которое генерирует случайные комбинации символов. Для этого мне нужна случайная генерация целых чисел произвольной длины. Поэтому я использую расширение GMP и особенно gmp_random_range(). Но мне нужно доказать ссылкой, например, что она криптографически безопасна. Или, по крайней мере, достаточно случайно.
Случайные функции GMP используют начальное число (gmp_random_seed), и если я не устанавливаю начальное значение, все выглядит достаточно случайным. Итак, я полагаю, что когда я не устанавливаю начальное число явно, оно берется из какого-то надежного случайного источника. Я не мог найти что-то четкое изложение такой вещи.
Кроме того, возможность посеять ГСЧ почти всегда является признаком отсутствия криптографической защиты. CSPRNG обычно загружаются автоматически из хорошего источника, предоставляемого ОС.
Как показано в «Инициализация случайного состояния», в документации GMP единственными алгоритмами генератора случайных чисел, включенными в GMP, являются:
Любопытно, что в документации GMP в «Случайное заполнение состояний» говорится, что «метод выбора начального числа имеет решающее значение, если сгенерированные числа должны использоваться для важных приложений, таких как генерация криптографических ключей», хотя ни один из алгоритмов, включенных в GMP, не подходит для криптографических вычислений. использовать.
Как оказалось, вы можете использовать random_bytes
или random_int
в PHP для генерации криптографических случайных чисел. Единственное, что осталось, — преобразовать числа, которые они предоставляют, в числа произвольной точности. Таким образом, вам придется преобразовывать эти случайные числа «вручную» с помощью арифметических функций GMP. У меня есть статья, в котором обсуждается, как преобразовывать случайные числа в различные распределения. Чтобы генерировать однородные случайные целые числа в заданном диапазоне, нужный вам алгоритм называется gmp_random_range
или RNDINT
в этой статье.
* Там, где речь идет об информационной безопасности, использование случайных чисел в качестве начального числа для некриптографического ГСЧ нецелесообразно, поскольку злоумышленник, получив достаточно случайных чисел, может затем работать в обратном направлении, чтобы получить начальное число, даже если начальное число было сгенерировано криптографически безопасным способом.
Если ваша цель — просто сгенерировать криптографически случайную строку символов, вам даже не нужно идти по пути GMP. Просто создайте строку по одному символу за раз, вызывая RNDINTEXC
для каждого символа, который вы хотите сгенерировать:
random_int
с максимальным размером списка (размер, который почти наверняка будет в диапазоне целых чисел, которые может обработать PHP), затем добавьте символ, найденный по заданному случайному индексу в списке (начиная с 0).Большое спасибо за ваш ответ. Я приму это, хотя я не против того, чтобы другие комментировали эту тему. Я хотел комментировать больше, но я ограничен 600 символами. Я включу последнюю часть. Обобщая: как автор своего программного обеспечения я должен быть в состоянии ответить на вопрос, являются ли сгенерированные комбинации криптографически безопасными. На данный момент я могу сказать: «Нет, это не так. Но рандомизация хороша (может быть)». Извините меня, если я сказал некоторые глупости здесь. (И я не упомянул - я использую PHP 7.2 в Linux)
Извините, что продолжаю комментировать, но есть идея, как использовать gmp_random_range в CS. Я могу заполнить GMP RNG выводом random_bytes, который точно является CS. Мне просто нужно рассчитать, сколько байтов запрашивать. Это зависит от количества чисел, которые мне нужны из gmp_random_range. У меня уже есть какая-то формула, она использует логарифм, а PHP GMP не имеет такой функции, но я нашел некоторые решения по этому поводу в SO. Я думаю, что раздавать семена перед каждым использованием, чтобы каждый результат был совершенно случайным. Планирую начать реализацию на следующей неделе. Пока это просто идея.
Опасность использования некриптографических RNG заключается в том, что злоумышленник, получив достаточно случайных чисел, может работать в обратном направлении, чтобы получить начальное число, даже если начальное число было сгенерировано криптографически безопасным способом. Для ваших целей, особенно если вы реализуете алгоритм, чувствительный к безопасности, вам может быть лучше использовать числа, заданные random_bytes
или random_int
напрямую, а не использовать их для заполнения некриптографического RNG, такого как найденный в GMP.
Спасибо! Но я имел в виду использование разных начальных значений для каждого вызова gmp_random_range. Поэтому я бы использовал random_bytes для случайности и функцию gmp для полезности диапазона (и, конечно, без ограничений типа int). Я имею в виду - одно семя - одно число. Я думаю, злоумышленнику не хватило бы цифр. Один - максимум.
В этом смысле знаете ли вы, что PHP random_int
уже генерирует криптографические случайные числа в заданном диапазоне целых чисел? Кроме того, у меня есть статья, в котором обсуждается, как преобразовывать случайные числа в различные распределения.
Конечно, я знаю о random_int. Я должен сказать немного о том, что я делаю. Комбинации символов я воспринимаю как числа в биективной системе счисления с другим основанием. Когда у меня есть набор символов, необходимое количество символов, я могу определить минимальное и максимальное значения, а затем взять случайное число между ними. Все очень большие, поэтому GMP. Я написал свой собственный класс, в котором есть методы для str<->num (GMP). На данный момент я не понимаю, как использовать random_int для получения номера GMP в диапазоне GMP. Если вы скажете мне, что это то, что вы имеете в виду - мне придется достаточно глубоко покопаться в вашей статье.
Наконец, я реализовал генерацию случайных чисел gmp, используя random_bytes и мою версию это.
Нет, gmp не стремится быть криптографически безопасным. Используйте, например, random_int или случайные_байты. В общем, если что-то явно не задокументировано как пригодное для криптографического использования, это не так.