Learn how to encrypt and decrypt values using Laravel’s Crypt facade with AES-256-CBC. Covers APP_KEY generation, model casting, key rotation, and practical examples.
Laravel’s encryption services provide a simple, convenient interface for encrypting and decrypting text via OpenSSL using AES-256 and AES-128 encryption.All of Laravel’s encrypted values are signed using a message authentication code (MAC).
This means that if an encrypted value is tampered with after encryption, it cannot be decrypted.
Before using the encrypter, set the key option in config/app.php.
This value is driven by the APP_KEY environment variable.Use php artisan key:generate to generate a cryptographically secure key using PHP’s secure random bytes generator.
php artisan key:generate
The key is normally generated automatically during Laravel’s installation and stored in your .env file.
Changing your encryption key logs out all authenticated user sessions because Laravel encrypts all cookies, including session cookies.
Data encrypted with your previous key also becomes unreadable.To mitigate this, list your previous encryption keys in APP_PREVIOUS_KEYS as a comma-delimited string.
Laravel always uses the current key for encryption. When decrypting, it first tries the current key and then falls back to previous keys in order.
This lets users continue using your application uninterrupted during key rotation.
Use the encryptString method on the Crypt facade to encrypt a value.
The result uses OpenSSL with AES-256-CBC and is signed with a MAC.
<?phpnamespace App\Http\Controllers;use Illuminate\Http\RedirectResponse;use Illuminate\Http\Request;use Illuminate\Support\Facades\Crypt;class DigitalOceanTokenController extends Controller{ /** * Store a DigitalOcean API token for the user. */ public function store(Request $request): RedirectResponse { $request->user()->fill([ 'token' => Crypt::encryptString($request->token), ])->save(); return redirect('/secrets'); }}
encryptString encrypts a string without serialization. Use encrypt for arrays and objects.
Method
Use
Crypt::encryptString($value)
Encrypt a plain string
Crypt::encrypt($value)
Serialize then encrypt (supports arrays and objects)
Use the decryptString method to decrypt an encrypted value.
If the value cannot be decrypted — for example, because the MAC is invalid — a DecryptException is thrown.
use Illuminate\Contracts\Encryption\DecryptException;use Illuminate\Support\Facades\Crypt;try { $decrypted = Crypt::decryptString($encryptedValue);} catch (DecryptException $e) { // Handle invalid or tampered data abort(400, 'Invalid data.');}
Method
Use
Crypt::decryptString($value)
Decrypt to a plain string
Crypt::decrypt($value)
Decrypt and unserialize (supports arrays and objects)
Once a cast is configured, encryption and decryption happen automatically when you get or set the attribute.
// Automatically encrypted before saving to the database$user->secret_note = 'My secret note';$user->save();// Automatically decrypted when retrievedecho $user->secret_note; // 'My secret note'
The encrypted:* casts use Crypt::encrypt and Crypt::decrypt internally.
Use a text or longText column type in your migrations to store encrypted values.