Создание криптографически защищенных жетонов

Чтобы создать 32-символьный токен для доступа к нашему API, мы в настоящее время используем:

$token = md5(uniqid(mt_rand(), true)); 

Я прочитал, что этот метод не криптографически безопасен, поскольку он основан на системных часах, и что openssl_random_pseudo_bytes будет лучшим решением, поскольку его было бы сложнее предсказать.

Если это так, каков будет эквивалентный код?

Я предполагаю что-то подобное, но я не знаю, правильно ли это …

 $token = md5(openssl_random_pseudo_bytes(32)); 

И какая длина имеет смысл, что я должен перейти к функции?

Вот правильное решение:

 $token = bin2hex(openssl_random_pseudo_bytes(16)); # or in php7 $token = bin2hex(random_bytes(16)); 

Если вы хотите использовать openssl_random_pseudo_bytes, лучше использовать реализацию CrytoLib, это позволит вам генерировать все буквенно-цифровые символы, приклеивая bin2hex вокруг openssl_random_pseudo_bytes, просто приведет к получению AF (кепок) и номеров.

Замените путь / на /, где вы поместите файл cryptolib.php (вы можете найти его на GitHub по адресу: https://github.com/IcyApril/CryptoLib )

 <?php require_once('path/to/cryptolib.php'); $token = CryptoLib::randomString(16); ?> 

Полную документацию CryptoLib можно найти по адресу: https://cryptolib.ju.je/ . Он охватывает множество других случайных методов, каскадное шифрование и генерацию хеширования и валидацию; но он там, если вам это нужно.

Если у вас есть криптографически безопасный генератор случайных чисел, вам не нужно хешировать его вывод. На самом деле вы этого не хотите. Просто используйте

 $token = openssl_random_pseudo_bytes($BYTES,true) 

Если $ BYTES – это много байтов данных, которые вы хотите. MD5 имеет 128-битный хеш, поэтому будут выполняться 16 байт.

В качестве побочного примечания ни одна из функций, которые вы вызываете в вашем исходном коде, не криптографически безопасна, большинство из них достаточно вредны, что использование одного из них может быть небезопасным даже в сочетании с другими защищенными функциями. MD5 имеет проблемы с безопасностью (хотя для этого приложения они могут быть неактуальными). Uniqid не только не генерирует криптографически случайные байты по умолчанию (так как он использует системные часы), добавленная энтропия, которую вы передаете, объединяется с использованием линейного конгруэнтного генератора, который не является криптографически безопасным. Фактически, это, вероятно, означает, что вы можете угадать все ваши ключи API, предоставленные для доступа к некоторым из них, даже если они не имели представления о стоимости ваших серверных часов. Наконец, mt_rand (), то, что вы используете в качестве дополнительной энтропии, также не является защищенным генератором случайных чисел.

В php нет простой функции, изменяющей строку байта непосредственно на строку символов, она должна быть реализована самостоятельно! Вот так: PHP Password Generator .