DEV Community

Tommy Hendrawan
Tommy Hendrawan

Posted on

Automatic Laravel Data Encryption with Eloquent

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:

$ composer require elgibor-solution/laravel-database-encryption
Enter fullscreen mode Exit fullscreen mode

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:

    'providers' => [
        ...
        \ESolution\DBEncryption\Providers\DBEncryptionServiceProvider::class,
    ],
Enter fullscreen mode Exit fullscreen mode

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:


    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'
        ];
    }
Enter fullscreen mode Exit fullscreen mode

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.

    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;
        }
    }
Enter fullscreen mode Exit fullscreen mode

Encrypt your current data

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

    php artisan encryptable:encryptModel 'App\User'
Enter fullscreen mode Exit fullscreen mode

Additionally you can decrypt it using the command below

    php artisan encryptable:decryptModel 'App\User'
Enter fullscreen mode Exit fullscreen mode

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

      $validator = validator(['email'=>'foo@bar.com'], ['email'=>'exists_encrypted:users,email']);
      $validator = validator(['email'=>'foo@bar.com'], ['email'=>'unique_encrypted:users,email']);
Enter fullscreen mode Exit fullscreen mode

Hope this package help other people that got same project requirement

Top comments (11)

Collapse
 
siv_casm profile image
Shivam Pandya

What about existing plain text data in database which are there before installing and configuring this package?

Collapse
 
tommyhendrawan profile image
Tommy Hendrawan

You can encrypt the old data with command below

    php artisan encryptable:encryptModel '<Your Model Path>'
Enter fullscreen mode Exit fullscreen mode

eg.

    php artisan encryptable:encryptModel 'App\User'
Enter fullscreen mode Exit fullscreen mode
Collapse
 
siv_casm profile image
Shivam Pandya

Thank you very much. :)

Thread Thread
 
codefinity profile image
Manav Misra

Nice of you to thank the author. Welcome to community! ๐Ÿค“

Collapse
 
galegobr01 profile image
galegobr01

@tommyhendrawan

How does it impact query performance when the encrypted field is an index?

Thanks for response.

Collapse
 
ibrahimgamal92 profile image
ibrahim-gamal-92

Are this encryption process being done with Private key? or any one install this packages can decrypt data

Collapse
 
tommyhendrawan profile image
Tommy Hendrawan

The package use laravel key that generated when you first setup the project

Collapse
 
jayanta_mondal_40bfc314d9 profile image
Jayanta Mondal

How to use orderBy encrypted column?

Collapse
 
constantinosergiou profile image
Constantinos Sergiou

the login auth controller is not working after i have add they packages any suggestions?

Collapse
 
khushbupatel17 profile image
khushbupatel17

Is this working with auth??

Collapse
 
arebfaraz profile image
Areb Faraz

How can i set encryption key other than .env file. I dont want to use .env file to keep encryption key