php-standard-library/secure-random
Generate cryptographically secure random tokens, passwords, nonces, and bytes in PHP. SecureRandom provides simple, reliable APIs built on native CSPRNG sources, suitable for authentication, CSRF protection, and other security-sensitive identifiers.
Installation
composer require php-standard-library/secure-random
No additional configuration is needed—it leverages PHP’s native random_bytes() and random_int().
First Use Case: Secure Token Generation
Replace insecure randomness (e.g., Str::random() or mt_rand()) with:
use SecureRandom\SecureRandom;
// Generate a 32-byte hex token (64 chars) for CSRF or auth
$token = SecureRandom::hex(32);
// Generate a 16-byte base64 token (24 chars) for URLs
$urlToken = SecureRandom::base64(16);
// Generate a secure integer (e.g., for lottery draws)
$randomInt = SecureRandom::int(1, 1000);
Where to Look First
hex(), base64(), int(), and bytes().app/Providers/AppServiceProvider.php for global replacements (e.g., overriding Str::random()).description.md for fallback behavior (e.g., if random_bytes() fails).Replacing Laravel’s Str::random()
Use SecureRandom for security-critical paths only. Example:
// Insecure (pseudo-random)
$oldToken = Str::random(32);
// Secure (cryptographically random)
$newToken = SecureRandom::hex(32);
Database UUIDs/IDs
// Generate a UUID-like hex string (16 bytes)
$uuid = SecureRandom::hex(16);
// For auto-increment IDs, use SecureRandom::int() if predictability is a risk
$id = SecureRandom::int(1, PHP_INT_MAX);
Password Reset Tokens
// Generate a URL-safe token (base64, no padding)
$token = SecureRandom::base64(32);
// Store in DB with `token` column (VARCHAR(44) for base64)
CSRF Protection
Override Laravel’s default token generation in AppServiceProvider:
use SecureRandom\SecureRandom;
public function boot()
{
view()->composer('*', function ($view) {
$view->with('csrf_token', SecureRandom::hex(32));
});
}
Encryption Nonces/IVs
// Generate a 16-byte IV for AES
$iv = SecureRandom::bytes(16);
Dependency Injection (Laravel) Bind the package to the container for type-hinted usage:
$this->app->singleton(SecureRandom::class, function ($app) {
return new SecureRandom();
});
Then inject via constructor:
public function __construct(private SecureRandom $secureRandom) {}
Token Generation Pipeline
SecureRandom::method(length).Bulk Operations For generating multiple tokens (e.g., batch invites):
$tokens = array_map(fn() => SecureRandom::hex(32), range(1, 100));
Note: Avoid in high-throughput loops—batch processing may impact performance.
Fallback Handling
If random_bytes() fails (e.g., low entropy), implement a retry mechanism:
$token = SecureRandom::hex(32);
if ($token === false) {
// Fallback to random_int() or throw an exception
throw new \RuntimeException("Secure random generation failed.");
}
Avoid Mixing with Str::random()
Reserve SecureRandom for security-sensitive paths. Use Str::random() for non-critical randomness (e.g., feature flags).
Database Schema Adjustments
hex() tokens: Use VARCHAR(64) (32 bytes × 2 hex chars).base64() tokens: Use VARCHAR(44) (32 bytes × 1.33 base64 chars).Testing
Mock SecureRandom in tests to avoid flakiness:
$this->app->instance(SecureRandom::class, Mockery::mock(SecureRandom::class));
Performance
Benchmark critical paths (e.g., auth token generation) to ensure latency is acceptable. Use random_int() for non-critical integers if speed is critical.
False Sense of Security
SecureRandom for non-security-critical paths (e.g., UI animations) adds unnecessary overhead.random_bytes() Failures
random_bytes() may return false.random_int():
$bytes = random_bytes(32);
if ($bytes === false) {
$bytes = random_int(0, PHP_INT_MAX); // Less secure fallback
}
Token Collisions
SecureRandom::int() or SecureRandom::hex().Laravel Caching Conflicts
SecureRandom may expose them if not invalidated properly.PHP Version Dependencies
random_int()/random_bytes().paragonie/random_compat as a polyfill for older PHP versions.Token Generation Failures Check system entropy:
# Linux
cat /proc/sys/kernel/random/entropy_avail
# macOS
sysctl kern.entropy.available
If entropy is low, restart the system or use a hardware RNG.
Unexpected false Returns
Wrap calls in error handling:
$token = SecureRandom::hex(32);
if ($token === false) {
Log::error("Secure random generation failed. Falling back to insecure method.");
$token = Str::random(32); // Not recommended for production!
}
class CustomSecureRandom extends SecureRandom {
public static function hex(int $bytes): string {
$bytes = max(1, $bytes); // Enforce minimum length
return parent::hex($bytes);
}
}
Custom Entropy Sources
Extend the package to use hardware RNGs (e.g., /dev/random):
class HardwareSecureRandom extends SecureRandom {
protected static function randomBytes(int $length): string {
$handle = fopen('/dev/random', 'rb');
$bytes = fread($handle, $length);
fclose($handle);
return $bytes;
}
}
Rate Limiting Add rate limiting to prevent abuse (e.g., in API token endpoints):
class RateLimitedSecureRandom extends SecureRandom {
private $throttler;
public function __construct(Throttler $throttler) {
$this->throttler = $throttler;
}
public static function hex(int $bytes): string {
$instance = new self(app(Throttler::class));
return $instance->generateHex($bytes);
}
private function generateHex(int $bytes): string {
$this->throttler->allow(1, 'secure-random');
return parent::hex($bytes);
}
}
Laravel Service Provider Bind the extended class to the container:
$this->app->singleton(SecureRandom::class, function ($app) {
return new RateLimitedSecureRandom($app->make(Throttler::class));
});
How can I help you explore Laravel packages today?