Back to Read More
LaravelPHP

Laravel Encryption

Nov 25, 2025

Encryption turns readable data into scrambled text that can only be read back with a secret key. Laravel uses AES-256-CBC encryption β€” one of the strongest encryption standards. It's two-way: you can encrypt data and later decrypt it back to the original value.

Encryption vs Hashing

EncryptionHashing
DirectionTwo-way (encrypt & decrypt)One-way (cannot reverse)
Use forData you need to read back (API keys, personal data)Data you never need to read (passwords)
Example"hello" β†’ "eyJpdiI6..." β†’ "hello""hello" β†’ "$2y$12$..." (cannot get "hello" back)

1. The Encryption Key (APP_KEY)

Laravel uses the APP_KEY in your .env file as the encryption key. This is generated when you create a Laravel project.

Terminal
# Generate a new app key
php artisan key:generate
.env
APP_KEY=base64:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Warning: Never share or expose your APP_KEY. If someone gets it, they can decrypt all your encrypted data. If you change it, all previously encrypted data becomes unreadable.

2. Encrypting & Decrypting

Basic Encryption
use Illuminate\Support\Facades\Crypt;

// Encrypt a value
$encrypted = Crypt::encryptString('my-secret-api-key');
// Result: "eyJpdiI6IkpRb0xLT..." (long scrambled string)

// Decrypt it back
$decrypted = Crypt::decryptString($encrypted);
// Result: "my-secret-api-key"
Encrypt any data type (not just strings)
use Illuminate\Support\Facades\Crypt;

// Encrypt arrays, numbers, objects β€” anything serializable
$encrypted = Crypt::encrypt(['key' => 'value', 'secret' => true]);
$decrypted = Crypt::decrypt($encrypted);
// Result: ['key' => 'value', 'secret' => true]

// Using the helper function
$encrypted = encrypt('my secret');
$decrypted = decrypt($encrypted);

3. Handling Decryption Errors

If decryption fails (wrong key, corrupted data), Laravel throws a DecryptException. Always handle this:

Safe decryption
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Support\Facades\Crypt;

try {
    $decrypted = Crypt::decryptString($encryptedValue);
} catch (DecryptException $e) {
    // Handle the error β€” data is corrupted or key changed
    return response()->json(['error' => 'Unable to decrypt data'], 500);
}

4. Auto-Encrypt Model Fields

Use Eloquent's encrypted cast to automatically encrypt/decrypt fields when saving/reading from the database:

app/Models/User.php
class User extends Model
{
    protected $casts = [
        'ssn'            => 'encrypted',         // Auto encrypt string
        'secret_data'    => 'encrypted:array',    // Auto encrypt array
        'api_key'        => 'encrypted',
    ];
}
Usage β€” automatic, no extra code needed
// Saving β€” automatically encrypted before storing in DB
$user = User::create([
    'name'    => 'John',
    'ssn'     => '123-45-6789',  // Stored encrypted in database
    'api_key' => 'sk-abc123',    // Stored encrypted in database
]);

// Reading β€” automatically decrypted when accessed
echo $user->ssn;      // "123-45-6789" (readable)
echo $user->api_key;  // "sk-abc123" (readable)

// In database, it looks like:
// ssn: "eyJpdiI6IkxRb0xLT0..." (encrypted gibberish)
Best practice: Use encrypted casts for sensitive data like SSNs, API keys, personal medical data, payment info β€” anything you need to store but must protect.

5. Practical Example

Storing third-party API credentials securely:

Migration
Schema::create('integrations', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')->constrained();
    $table->string('provider');        // "stripe", "github"
    $table->text('access_token');      // Will be encrypted
    $table->text('refresh_token');     // Will be encrypted
    $table->timestamps();
});
app/Models/Integration.php
class Integration extends Model
{
    protected $fillable = ['user_id', 'provider', 'access_token', 'refresh_token'];

    protected $casts = [
        'access_token'  => 'encrypted',
        'refresh_token' => 'encrypted',
    ];
}

// Save β€” tokens are auto-encrypted
Integration::create([
    'user_id'       => auth()->id(),
    'provider'      => 'stripe',
    'access_token'  => 'sk_live_abc123xyz',   // Encrypted in DB
    'refresh_token' => 'rt_live_def456uvw',   // Encrypted in DB
]);

// Read β€” tokens are auto-decrypted
$integration = Integration::where('provider', 'stripe')->first();
echo $integration->access_token; // "sk_live_abc123xyz" (readable)

Summary

  • βœ“AES-256-CBC β€” Laravel uses strong encryption by default
  • βœ“APP_KEY β€” the secret key that encrypts everything
  • βœ“Crypt facade β€” encrypt() / decrypt() for manual use
  • βœ“Encrypted casts β€” auto-encrypt model fields in database
  • βœ“Two-way β€” use for data you need to read back (not passwords)

Β© 2026 Koeuk KOS. All rights reserved.

Built with Nuxt.js, Vue.js & Tailwind CSS