Automatic Laravel Data Encryption with Eloquent
Tags: laravel, php, encryption, eloquent
Published: 2020-12-19 03:20:13

Few months ago i got laravel project requirement that need me to encrypt all user information that stored at database and the encrypted information also `must be searchable`.

I try to google search and found some laravel package that enable eloquent to `automatically encrypt data` when do save and `automatically decrypt data` when load. Sadly most of the package not support search at the encrypted information.

Start from package that i found, i try to modify and create new package that suit my project requirement like below

## Installation

### Step 1: Composer

Via Composer command line:

```bash
$ composer require elgibor-solution/laravel-database-encryption
```

### Step 2: Add ServiceProvider to your app/config.php file (Laravel 5.4 or below)
Add the service provider to the providers array in the config/app.php config file as follows:
```php
    'providers' => [
        ...
        \ESolution\DBEncryption\Providers\DBEncryptionServiceProvider::class,
    ],
```

## Usage

Use the `EncryptedAttribute` trait in any Eloquent model that you wish to apply encryption
to and define a `protected $encrypted` array containing a list of the attributes to encrypt.

For example:

```php
    
    use ESolution\DBEncryption\Traits\EncryptedAttribute;

    class User extends Eloquent {
        use EncryptedAttribute;
       
        /**
         * The attributes that should be encrypted on save.
         *
         * @var array
         */
        protected $encryptable = [
            'first_name', 'last_name'
        ];
    }
```

By including the `EncryptedAttribute` trait, the `setAttribute()`, `getAttribute()` and `getAttributeFromArray()`
methods provided by Eloquent are overridden to include an additional step.

### Searching Encrypted Fields Example:
Searching encrypted field can be done by calling the `whereEncrypted` and `orWhereEncrypted` functions
similar to laravel eloquent `where` and `orWhere`.


```php
    namespace App\Http\Controllers;

    use App\User;
    class UsersController extends Controller {
        public function index(Request $request)
        {
            $user = User::whereEncrypted('first_name','john')
                        ->orWhereEncrypted('last_name','!=','Doe')->firstOrFail();
            
            return $user;
        }
    }
```

### Encrypt your current data
 If you have current data in your database you can encrypt it with the command below

```php 
    php artisan encryptable:encryptModel 'App\User'
```
    
 Additionally you can decrypt it using the command below

```php
    php artisan encryptable:decryptModel 'App\User'
```

 Note: You must implement first the `Encryptable` trait and set `$encryptable` attributes

### Exists and Unique Validation Rules
 If you are using exists and unique rules with encrypted values replace it with exists_encrypted and unique_encrypted 
    
```php      
      $validator = validator(['email'=>'foo@bar.com'], ['email'=>'exists_encrypted:users,email']);
      $validator = validator(['email'=>'foo@bar.com'], ['email'=>'unique_encrypted:users,email']);
```


Hope this package help other people that got same project requirement