Laravel: Шифрование данных моделей с помощью кастов

Источник: «Laravel: Encrypt Models Data with Casts»
Если вы хотите избежать хранения конфиденциальных данных БД (например, номеров паспортов) в виде обычного текста, Laravel может зашифровать их в Моделях Eloquent, просто присвоив им значение encrypted. Давайте посмотрим, как это работает.

Это выглядит примерно так:

Пример зашифрованных данных
Пример хранения данных в БД зашифрованных Моделью Eloquent

Мы не хотим, чтобы номера паспортов пользователей хранились в нашей базе данных открытым текстом, поэтому шифрование является отличным способом их защиты. При этом можно зашифровать любые данные в ваших моделях, а не только пользовательские.

Настройка базы данных

Для базы данных не требуется ничего особенного. Вы должны убедиться, что столбец, который вы хотите зашифровать, является string/text (в зависимости от объёма данных), даже если исходное значение содержит только цифры, например, номера паспортов в нашем случае.

Настройка модели

В модель необходимо добавить свойство protected $casts и столбец, который мы хотим зашифровать. В нашем случае это passport_number:

// ...

protected $casts = [
'passport_number' => 'encrypted',
];

// ...

Вот и все! Теперь при сохранении номера паспорта в пользовательской модели он будет зашифрован, а при обращении к нему — расшифрован. Как это круто!

Важное Предупреждение: Защитите свой ключ приложения

Упомянутый выше алгоритм шифрования основан на значении APP_KEY вашего приложения. В файле .env должно быть примерно следующее:

APP_KEY=base64:QikAJAlo0evYLq2RYFxGv/PRrSIfJcNDj2qiFRp1oUs=

Говоря о шифровании, следует помнить о безопасности APP_KEY. Если кто-то получит к нему доступ, он сможет расшифровать все ваши зашифрованные данные. Поэтому, пожалуйста, храните его в безопасности и никому не сообщайте.

Что произойдёт, если изменить ключ приложения

Ваш APP_KEY генерируется заново каждый раз, когда вы выполняете php artisan key:generate. Но что произойдёт с вашими зашифрованными данными, если вы измените APP_KEY?

Зашифрованные данные будут потеряны!

Именно так. Если вы измените APP_KEY, все ваши зашифрованные данные будут потеряны. Это связано с тем, что данный ключ используется для шифрования/дешифрования, и его изменение приводит к нарушению процесса дешифрования. Просто посмотрите на этот пример:

array: 10// routes/web.php:23
0 => array:7 [
"id" => 1
"name" => "Prof. Flossie Rutherford IV"
"email" => "hulda.spencer@example.org"
"email_verified_at" => "2023-09-06T15:55:18.000000Z"
"passport_number" => "8864880769"
"created_at" => "2023-09-06T15:55:18.000000%"
"updated_at" => "2023-09-06T15:55:18.000000Z"
1 => array:7 [
"id" => 2
"name" => "Dylan Lueilwitz"
"email" => "qfritsch@example.com"
"email_verified_at" => "2023-09-06T15:55:18.000000Z"
"passport_number" => "3324108737"
"created_at" => "2023-09-06T15:55:18.000000Z"
"updated_at" => "2023-09-06T15:55:18.000000Z"
2 => array:7 [
"id" => 3
"name" => "Mary Harvey V"
"email" => "frederik.kreiger@example.net"
"email_verified_at" => "2023-09-06T15:55:18.000000Z"
"passport_number" => "6595462478"
"created_at" => "2023-09-06T15:55:18.000000Z"
"updated_at" => "2023-09-06T15:55:18.000000Z"
3 => array:7 [
"id" => 4
"name" => "Enid Monahan"
"email" => "dave.nitzsche@example.com"
"email_verified_at" => "2023-09-06T15:55:18.000000Z"
"passport_number" => "5141691749"
"created_at" => "2023-09-06T15:55:18.000000Z"
"updated_at" => "2023-09-06T15:55:18.000000%"

А если мы поменяем ключ:

Illuminate\Contracts\Encryption\DecryptException

The MAC is invalid.

Поэтому основная идея заключается в следующем: НЕ запускайте key:generate на продакшен сервере.

Берегите APP_KEY и не теряйте его. Неплохо хранить его резервную копию в надёжном месте.

Дополнительные материалы

Предыдущая Статья

Ошибка Livewire 3 и Laravel Breeze: Конфликт Alpine.js

Следующая Статья

Использование Bun в качестве менеджера пакетов в PHP проектах