> ## Content Index
> Fetch the complete content index at: https://securinglaravel.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Security Tip: Custom Encryption Keys for Cast Model Attributes
- URL: https://securinglaravel.com/security-tip-custom-encryption-key/
- Published: 2021-09-05T14:00:50.000Z
- Updated: 2024-09-16T12:57:43.000Z
- Description: [Tip#1] A simple but quite important tip, how to use a custom encryption key for encrypted casting within Models.
- Author: Stephen Rees-Carter
- Tags: Security Tips, Cryptography, Secrets

Laravel allows you to [cast model attributes as encrypted strings](https://laravel.com/docs/eloquent-mutators?ref=securinglaravel.com#encrypted-casting), when storing them in the database. This gives you added security for any values that are sensitive (such as Personally identifiable information, *PII*), including complex structures such as *arrays*, *collections*, and even *objects*.

```
class User extends Model 
{
    protected $casts = ['secrets' => 'encrypted:array']; 
}
```

The downside is, Laravel uses the default application encryption key to encrypt the value. This opens up the potential risk of a hacker being able to encrypt a specially crafted payload and then retrieve the encrypted value somehow.

The solution is quite easy though, we can use the `Model::encryptUsing()` method, which was [added to Laravel by Illia Sakovich](https://github.com/laravel/framework/pull/35080?ref=securinglaravel.com). It allows us to define a custom Encrypter for use by the Model when encrypting data, which lets us use a different encryption key.

First, generate a new encryption key and add it into `.env`:

```
php artisan key:generate --show
```

Next, load that into your application config - something like `database.encryption_key` might make sense, given it’s for the database model encryption.

Finally, update your `AppServiceProvider` to load the new encryption key into the model:

```
namespace App\Providers;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Encryption\Encrypter;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        $key = $this->databaseEncryptionKey();
        $cipher = config('app.cipher');
        Model::encryptUsing(new Encrypter($key, $cipher));
    }

    protected function databaseEncryptionKey(): ?string
    {
        $key = config('database.encryption_key');
        return base64_decode(Str::after($key, 'base64:'));
    }
}
```

*You can find all the code in this Gist:* [*https://gist.github.com/valorin/ce58cf55dedaf759b3aa7fcfb2fcf613*](https://gist.github.com/valorin/ce58cf55dedaf759b3aa7fcfb2fcf613?ref=securinglaravel.com)*.*

That should do it.

Your encrypted casts should now use a custom key, keeping your application key safe.

💡

**Don’t change your key after data is stored in the database, or you’ll lose access to the original data with the old key!*

---

**Found this security tip helpful?* Don't forget to* [*subscribe*](https://securinglaravel.com/#/portal/signup) *to receive new* [*Security Tips*](https://securinglaravel.com/tag/tips/) *each week, and upgrade to a* [*premium subscription*](https://securinglaravel.com/#/portal/signup) *to receive monthly* [*In Depth articles*](https://securinglaravel.com/tag/in-depth/)*, or toss a coin in the* [*tip jar*](https://securinglaravel.com/#/portal/support)*.*

*You can follow Stephen on* [*Twitter*](https://twitter.com/valorin?ref=securinglaravel.com)*,* [*Fediverse*](https://phpc.social/@valorin?ref=securinglaravel.com)*,* [*LinkedIn*](https://www.linkedin.com/in/stephen-rees-carter/?ref=securinglaravel.com)*,* [*Pinkary*](https://pinkary.com/@valorin?ref=securinglaravel.com)*,* [*Bluesky*](https://bsky.app/profile/valorin.bsky.social?ref=securinglaravel.com)*, and* [*Threads*](https://www.threads.net/@valorinsrc?ref=securinglaravel.com)*, and reach out if you're looking for a* [*Laravel Security Audit and Penetration Test*](https://stephenreescarter.net/laravel-security-audits-and-pentesting/?utm%5Fsource=securinglaravel.com) *or a budget-friendly* [*Security Review*](https://stephenreescarter.net/laravel-security-reviews/?utm%5Fsource=securinglaravel.com)*.*

*Finally, to learn more about security through a series of interactive challenges, check out Stephen's new course:* [*Practical Laravel Security*](https://practicallaravelsecurity.com/?utm%5Fsource=securinglaravel.com)*.*