Криптографически безопасная случайная ASCII-строка в PHP - PullRequest
0 голосов
/ 12 января 2019

Я знаю о random_bytes() в PHP 7, и я хочу использовать его для генерации криптографически безопасной (например, трудно угадываемой) случайной строки для использования в качестве одноразового токена или для более длительного хранения в cookie.

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

Есть идеи?

Ответы [ 3 ]

0 голосов
/ 12 января 2019

К сожалению, Питер О. удалил свой ответ, получив негативное внимание в очереди на рассмотрение, возможно, потому, что он сформулировал его как вопрос. Я считаю, что это законный ответ, поэтому я повторю его.

Одним из простых решений является кодирование случайных данных в алфавит base64 с использованием base64_encode(). Это не даст «полный диапазон ASCII», как вы просили, но даст вам большую его часть. Еще больший диапазон ASCII выводится подходящим энкодером base85, но у php нет встроенного. Вы можете найти множество кодировщиков base85 с открытым исходным кодом для php. По моему мнению, уменьшение длины base85 по сравнению с base64 вряд ли будет стоить дополнительного кода, который вы должны поддерживать.

0 голосов
/ 13 января 2019

Давайте рассмотрим буквы, которые будут использоваться. Для простоты я предполагаю, что вы собираетесь использовать только большие и маленькие английские буквы. Это означает, что у вас есть 26 больших букв и 26 маленьких букв, 52 различных возможных значения. Если мы рассмотрим байтовый массив из n элементов как число из n цифр в базе 256 и преобразуем это число в число 52, где A равно 0, B равно 1, C равно 2, ..., a равно 26, ..., z равно 51, тогда преобразование этих цифр в соответствующие буквы приведет к желаемому тексту.

0 голосов
/ 12 января 2019

Лично я просто использую библиотеку GUID и объединяю пару GUID, чтобы получить длинную уникальную строку токена. У вас также есть возможность удалить дефисы, чтобы вам было трудно узнать источник, и если вы хотите сделать его еще более сложным, вы можете случайно сократить строку до 10 символов, чтобы добавить сложности к ее неизвестной длине.

Я использую эту библиотеку для генерации моих GUID

https://packagist.org/packages/ramsey/uuid

use Ramsey\Uuid\Uuid;
$token = Uuid::uuid4() . '-' . Uuid::uuid4();

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

На самом деле, если бы вы могли безопасно генерировать массив случайных чисел в диапазоне допустимых кодов символов ascii, то вы могли бы преобразовать весь случайный массив кодов в соответствующий символ ascii и объединить их вместе в одну строку.

function randomAsciiString($length) {
    return implode('', array_map(
        function($value) {
            return chr($value);
        },
        array_map(
            function($value) {
                return random_int(33, 126);
            },
            array_fill(0, $length - 1, null)
        )
    ));
}
echo randomAsciiString(128);                  // Normal 128 char string
echo randomAsciiString(random_int(118, 128)); // obfuscated length char string for extra complexity.

конечно, хотя ... вам следует помнить, что вы используете все стандартные клавиши на клавиатуре, и некоторые из этих символов могут расстраивать чувствительные вещи (например, кавычки и т. Д.)

...