lumensistemas / encryption-laravel
Sodium-based encryption, decryption, and blind indexing for Laravel applications.
Package info
github.com/lumensistemas/encryption-laravel
pkg:composer/lumensistemas/encryption-laravel
Fund package maintenance!
Requires
- php: >=8.4
- ext-mbstring: *
- ext-sodium: *
- illuminate/support: ^12.0|^13.0
Requires (Dev)
- laravel/pint: ^1.0
- orchestra/testbench: ^10.0|^11.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-type-coverage: ^4.0
- phpstan/phpstan: ^2.1
- rector/rector: ^2.3
This package is auto-updated.
Last update: 2026-04-02 07:41:13 UTC
README
Sodium-based encryption, decryption, and blind indexing for Laravel. Provides Eloquent casts for transparent field-level encryption with optional authorization hooks (e.g. LGPD/GDPR compliance).
Installation
composer require lumensistemas/encryption-laravel
Publish the configuration file:
php artisan vendor:publish --tag=encryption-laravel-config
Generate key files:
php artisan encryption:generate-keys
This creates storage/encryption.key and storage/authentication.key with 0600 permissions.
You can specify a custom directory:
php artisan encryption:generate-keys --path=/etc/secrets
Use --force to overwrite existing key files.
Add the key file paths to .env:
ENCRYPT_ENC_KEY_PATH=/path/to/your/app/storage/encryption.key ENCRYPT_AUTH_KEY_PATH=/path/to/your/app/storage/authentication.key
Security: Keys are read from files rather than environment variables. This prevents accidental exposure through
phpinfo(), debug pages, logs, or process listings. Key files should have restrictive permissions (600) and be excluded from version control.
Usage
Facade
use LumenSistemas\Encrypt\Facades\Encryption; use LumenSistemas\Encrypt\ValueObjects\SecretString; // Encrypt & decrypt $ciphertext = Encryption::encrypt(new SecretString('secret')); $plaintext = Encryption::decrypt($ciphertext)->get(); // 'secret' // Hash & verify (blind index) $hash = Encryption::hash(new SecretString('secret')); Encryption::verify(new SecretString('secret'), $hash); // true
Eloquent Casts
AsEncryptedString
Encrypts on write, decrypts on read:
use LumenSistemas\Encrypt\Casts\AsEncryptedString; class User extends Model { protected $casts = [ 'cpf' => AsEncryptedString::class, ]; }
AsBlindIndex
Stores a deterministic hash for searching encrypted columns:
use LumenSistemas\Encrypt\Casts\AsBlindIndex; use LumenSistemas\Encrypt\Casts\AsEncryptedString; class User extends Model { protected $casts = [ 'email_encrypted' => AsEncryptedString::class, 'email_index' => AsBlindIndex::class, ]; } // Query by blind index use LumenSistemas\Encrypt\Facades\Encryption; use LumenSistemas\Encrypt\ValueObjects\SecretString; $user = User::where('email_index', Encryption::hash(new SecretString($email)))->first();
Authorization & Audit Hook
Register a callback to authorize and/or log access before decryption. This is useful for LGPD/GDPR compliance:
use LumenSistemas\Encrypt\Casts\AsEncryptedString; // In a ServiceProvider boot(): AsEncryptedString::authorizeUsing(function (Model $model, string $key) { // Log every access AuditLog::record(auth()->user(), $model, $key); // Deny or mask if (! auth()->user()->can('view-sensitive', $model)) { return '***.***.***-**'; // return masked value instead of decrypting } return true; // allow decryption });
The callback receives (Model $model, string $key, array $attributes) and should:
- Return
trueto allow decryption - Return a
stringto return a masked value (skips decryption entirely) - Throw an exception to deny access
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.