Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як правильно генерувати випадкові числа й токени в PHP?

Не всі генератори випадкових чисел однакові. Для безпеки потрібен криптографічно стійкий генератор (CSPRNG), результат якого неможливо передбачити.

Для токенів, паролів, кодів підтвердження - лише CSPRNG:

random_int(100000, 999999);          // 6-значний код підтвердження
bin2hex(random_bytes(32));           // 64-символьний токен
Str::random(40);                     // у Laravel - теж на random_bytes

Чого не використовувати для безпеки:

  • rand(), mt_rand() - Mersenne Twister: швидкий, але передбачуваний. Знаючи кілька результатів, можна відновити внутрішній стан і передбачити наступні.
  • uniqid() - це час з мікросекундами, а не випадковість.
  • md5(time()), sha1(microtime()) - хеш передбачуваного значення лишається передбачуваним.
  • shuffle(), array_rand(), str_shuffle() - використовують нестійкий генератор.

Розширення Random (PHP 8.2) - об'єктний API з явним вибором рушія:

use Random\Randomizer;
use Random\Engine\Secure;
use Random\Engine\Mt19937;

$secure = new Randomizer(new Secure());          // CSPRNG за замовчуванням
$secure->getBytesFromString('ABCDEFGHJKLMNPQRSTUVWXYZ23456789', 8);   // код без схожих символів
$secure->shuffleArray($items);                   // безпечне перемішування

$seeded = new Randomizer(new Mt19937(42));       // відтворюваний: та сама послідовність з тим самим seed
$seeded->getInt(1, 100);

Відтворювана (seeded) випадковість корисна поза безпекою: тести, генерація даних, детерміновані вибірки («та сама випадкова добірка для того самого користувача сьогодні»).

Порівняння токенів - через hash_equals(), а зберігати токени доступу в базі краще хешованими (як паролі, але достатньо hash('sha256', ...), бо токен і так довгий і випадковий).

Докладніше в документації: Розширення Random

Схожі питання