Allow you to encrypt model's fields. You can add a hashed field to allow SQL query.
You can install the package via composer:
composer require webqamdev/encryptable-fields
You can publish the configuration via Artisan:
php artisan vendor:publish --provider="Webqamdev\EncryptableFields\EncryptableFieldsServiceProvider"
To work with this package, you need to use our EncryptableFields
trait in your models, then override
the $encryptable
property. This array allows you to define encryptable attributes in your model.
You can also add attributes to contain a hash of the non encrypted value, which might be useful in order to execute a fast full match for a given searched value.
To do so, you need to use the $encryptable
property as an associative array, where encryptable attributes are keys and
associated hashed attributes are values.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Webqamdev\EncryptableFields\Models\Traits\EncryptableFields;
class User extends Model
{
use EncryptableFields;
const COLUMN_LASTNAME = 'lastname';
const COLUMN_LASTNAME_HASH = 'lastname_hash';
const COLUMN_FIRSTNAME = 'firstname';
const COLUMN_FIRSTNAME_HASH = 'firstname_hash';
const COLUMN_EMAIL = 'mail';
/**
* The attributes that should be encrypted in database.
*
* @var string[]
*/
protected $encryptable = [
self::COLUMN_FIRSTNAME => self::COLUMN_FIRSTNAME_HASH,
self::COLUMN_LASTNAME => self::COLUMN_LASTNAME_HASH,
self::COLUMN_EMAIL,
];
To create a new model, simply do it as before:
User::create(
[
User::COLUMN_FIRSTNAME => 'watson',
User::COLUMN_LASTNAME => 'jack',
]
);
To find a model from a hashed value:
User::where(User::COLUMN_FIRSTNAME_HASH, User::hashValue('watson'))->first();
or use the model's local scope:
User::whereEncrypted(User::COLUMN_FIRSTNAME, 'watson')->first();
An auth provider, eloquent-hashed
, is registered by this package and allows to authenticate users on a hashed
attribute, per example an email. To use it, simply change your auth configuration as follows:
return [
// ...
'providers' => [
'users' => [
'driver' => 'eloquent-hashed',
'model' => App\Models\User::class,
],
],
// ...
];
MySQL
and MariaDB both provide an aes_decrypt
function, allowing to decrypt values
directly when querying. It then becomes possible to use this function to filter or sort encrypted values.
However, Laravel default encrypter only handles AES-128-CBC
and AES-256-CBC
cipher methods, where MySQL
and MariaDB
requires AES-128-ECB
. We're going to use two different keys.
To do so, add the following variable to your .env
file:
APP_DB_ENCRYPTION_KEY=
and run php artisan encryptable-fields:key-generate
command to generate a database encryption key.
Then, it is required to override Laravel's default encrypter, which is done in DatabaseEncrypter.php.
Include DatabaseEncryptionServiceProvider in
your config/app.php
, so that a singleton instance will be registered in your project, under databaseEncrypter
key:
return [
// ...
'providers' => [
// ...
/*
* Package Service Providers...
*/
Webqamdev\EncryptableFields\Providers\DatabaseEncryptionServiceProvider::class,
// ...
],
// ...
];
Finally, override the package configuration in encryptable-fields.php
file:
return [
// ...
// Need to implement EncryptionInterface
'encryption' => Webqamdev\EncryptableFields\Services\DatabaseEncryption::class,
// ...
];
=
instead of like
operator), which means it won't handle object instances or arrays.
If you're using Laravel Backpack in your project, a trait EncryptedSearchTrait provides methods to customize search and order logics.
use Illuminate\Database\Eloquent\Builder;
CRUD::addColumn([
// ...
'searchLogic' => function (Builder $query, array $column, string $searchTerm): void {
$this->encryptedSearchLogic($query, $column['name'], $searchTerm);
},
'orderLogic' => function (Builder $query, array $column, string $columnDirection): void {
$this->encryptedOrderLogic($query, $column['name'], $columnDirection);
},
// ...
]);
This package comes with some rules to validate existence and uniqueness for a hashed or encrypted attribute.
They work as extensions for Illuminate\Validation\Rules\Exists
and Illuminate\Validation\Rules\Unique
.
use Webqamdev\EncryptableFields\Rules\Exists\Hashed;
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules(): array
{
return [
'email' => [
new Hashed(User::class, 'email'),
// or new Hashed('users', 'email'),
],
];
}
and
use Webqamdev\EncryptableFields\Rules\Unique\Hashed;
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules(): array
{
return [
'email' => [
new Hashed(User::class, 'email'),
// or new Hashed('users', 'email'),
],
];
}
use Webqamdev\EncryptableFields\Rules\Exists\Encrypted;
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules(): array
{
return [
'email' => [
new Encrypted(User::class, 'email'),
// or new Encrypted('users', 'email'),
],
];
}
and
use Webqamdev\EncryptableFields\Rules\Unique\Encrypted;
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules(): array
{
return [
'email' => [
new Encrypted(User::class, 'email'),
// or new Encrypted('users', 'email'),
],
];
}
If your application use spatie/laravel-activitylog
or webqamdev/activity-logger-for-laravel :
Add HasEncryptableFieldsLog
trait in each model with logs.
This trait print encrypted values in log instead of decrypt values.
composer test
Please see CHANGELOG for more information what has changed recently.
Please see CONTRIBUTING for details.
The MIT License (MIT). Please see License File for more information.
This package was generated using the Laravel Package Boilerplate.