> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Encryption

> Learn how to encrypt and decrypt values using Laravel's Crypt facade and AES-256-CBC. Covers generating APP_KEY, model casts, and safely storing personal data.

## What is the Crypt facade

Laravel's encryption service provides a simple interface for encrypting and decrypting values using **OpenSSL** with AES-256-CBC (or AES-128-CBC).

All values encrypted by Laravel are signed with a **message authentication code (MAC)**.
This ensures that any tampering with the encrypted value will prevent it from being decrypted.

```mermaid theme={null}
flowchart LR
    A["Plaintext data"] -->|"Crypt::encryptString()"| B["Encrypted value<br>(signed with MAC)"]
    B -->|"Crypt::decryptString()"| A
    B -->|Tamper detected| C["DecryptException"]
```

***

## Configuration

### Generating the APP\_KEY

Before using encryption, you need to set the `key` value in `config/app.php`.
This value is loaded from the `APP_KEY` environment variable.

Use the `php artisan key:generate` command to generate a secure key.
It generates a cryptographically secure key using PHP's secure random number generator.

```shell theme={null}
php artisan key:generate
```

It's typically generated automatically when you install Laravel. The generated key is stored in the `.env` file.

```ini theme={null}
APP_KEY=base64:J63qRTDLub5NuZvP+kb8YIorGS6qFYHKVo6u7179stY=
```

<Warning>
  Never expose `APP_KEY`. If this key leaks, all encrypted data can be decrypted.
</Warning>

### Rotating the encryption key

When you change the encryption key, all authenticated user sessions are logged out.
This is because Laravel encrypts all cookies, including session cookies.

Also, data encrypted with the previous key can no longer be decrypted.

To mitigate this, you can list old keys separated by commas in `APP_PREVIOUS_KEYS`.

```ini theme={null}
APP_KEY="base64:J63qRTDLub5NuZvP+kb8YIorGS6qFYHKVo6u7179stY="
APP_PREVIOUS_KEYS="base64:2nLsGFGzyoae2ax3EF2Lyq/hH6QghBGLIq5uL+Gp8/w="
```

Laravel always uses the current key to encrypt, but when decrypting, if it fails with the current key it tries the previous keys in order.
This allows users to continue using the application during key rotation.

***

## Encryption

Use the `encryptString` method on the `Crypt` facade to encrypt a value.
The encrypted value uses OpenSSL with AES-256-CBC and is signed with a MAC.

```php theme={null}
<?php

namespace App\Http\Controllers;

use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Crypt;

class DigitalOceanTokenController extends Controller
{
    /**
     * Store the user's API token.
     */
    public function store(Request $request): RedirectResponse
    {
        $request->user()->fill([
            'token' => Crypt::encryptString($request->token),
        ])->save();

        return redirect('/secrets');
    }
}
```

<Tip>
  `encryptString` encrypts a string **without** serialization. To encrypt objects or arrays, use `encrypt`.
</Tip>

| Method                         | Purpose                                                                 |
| ------------------------------ | ----------------------------------------------------------------------- |
| `Crypt::encryptString($value)` | Encrypts a string as-is                                                 |
| `Crypt::encrypt($value)`       | Serializes the value and then encrypts it (supports arrays and objects) |

***

## Decryption

Use the `decryptString` method on the `Crypt` facade to decrypt an encrypted value.
If decryption fails (for example, if the MAC is invalid), a `DecryptException` is thrown.

```php theme={null}
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Support\Facades\Crypt;

try {
    $decrypted = Crypt::decryptString($encryptedValue);
} catch (DecryptException $e) {
    // Handle decryption failure
    abort(400, 'Invalid data.');
}
```

| Method                         | Purpose                                                 |
| ------------------------------ | ------------------------------------------------------- |
| `Crypt::decryptString($value)` | Decrypts as a string                                    |
| `Crypt::decrypt($value)`       | Decrypts and unserializes (supports arrays and objects) |

***

## Model casts

Using the `encrypted` cast on an Eloquent model, an attribute is automatically encrypted and decrypted.

```php theme={null}
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    protected function casts(): array
    {
        return [
            'secret_note'    => 'encrypted',           // String encryption
            'profile_data'   => 'encrypted:array',     // Encrypt and store an array
            'preferences'    => 'encrypted:collection',// Encrypt and store a collection
            'metadata'       => 'encrypted:object',    // Encrypt and store an object
            'settings'       => 'encrypted:json',      // Encrypt and store as JSON
        ];
    }
}
```

Once the cast is set up, values are automatically encrypted and decrypted when assigning to or reading from the model.

```php theme={null}
// Automatically encrypted and stored in the DB
$user->secret_note = 'Secret note';
$user->save();

// Automatically decrypted on retrieval
echo $user->secret_note; // 'Secret note'
```

<Info>
  The `encrypted:*` casts internally use `Crypt::encrypt` and `Crypt::decrypt`.
  A `text` or `longText` database column type is recommended.
</Info>

***

## Practical example: encrypting personal information

A typical pattern for securely storing personal information (national ID numbers, credit card numbers, etc.) in the database.

### Migration

```php theme={null}
Schema::create('profiles', function (Blueprint $table) {
    $table->id();
    $table->foreignId('user_id')->constrained();
    $table->text('my_number')->nullable();     // Store encrypted values in text
    $table->text('bank_account')->nullable();
    $table->timestamps();
});
```

### Model

```php theme={null}
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Profile extends Model
{
    protected $fillable = ['user_id', 'my_number', 'bank_account'];

    protected function casts(): array
    {
        return [
            'my_number'    => 'encrypted',
            'bank_account' => 'encrypted',
        ];
    }
}
```

### Controller

```php theme={null}
use App\Models\Profile;
use Illuminate\Http\Request;

class ProfileController extends Controller
{
    public function store(Request $request)
    {
        $request->validate([
            'my_number'    => ['required', 'string'],
            'bank_account' => ['required', 'string'],
        ]);

        // The model automatically encrypts and stores the values
        Profile::create([
            'user_id'      => $request->user()->id,
            'my_number'    => $request->my_number,
            'bank_account' => $request->bank_account,
        ]);

        return redirect('/profile');
    }

    public function show(Request $request)
    {
        $profile = $request->user()->profile;

        // The model automatically decrypts on return
        return view('profile.show', ['profile' => $profile]);
    }
}
```

***

## Summary

| What you want to do            | How                                  |
| ------------------------------ | ------------------------------------ |
| Generate APP\_KEY              | `php artisan key:generate`           |
| Encrypt a string               | `Crypt::encryptString($value)`       |
| Decrypt a string               | `Crypt::decryptString($value)`       |
| Encrypt an array/object        | `Crypt::encrypt($value)`             |
| Auto-encrypt a model attribute | `'column' => 'encrypted'` cast       |
| Key rotation                   | List old keys in `APP_PREVIOUS_KEYS` |

## Next steps

<Columns cols={2}>
  <Card title="Hashing" icon="lock" href="/en/hashing">
    Learn how to securely hash and verify passwords.
  </Card>

  <Card title="Authorization" icon="shield" href="/en/authorization">
    Learn about access control using policies and gates.
  </Card>
</Columns>


## Related topics

- [Redis](/en/redis.md)
- [OAuth 2.0 Authentication - Google Sheets API for Laravel](/en/packages/laravel-google-sheets/oauth.md)
- [Configuration](/en/configuration.md)
- [Routing](/en/routing.md)
- [Directory structure](/en/directory-structure.md)
