Tuesday 17 October 2017

Encryption user data in Laravel

Hi Everybody,

As you know, if you want user data(email, name etc) security in db, then you must encrypt data.
So at the time of adding data you need to encrypt data and at the time of retrieve data you need to decrypt data.
Below is the implementation of encryption and decryption of user data in Laravel

in Model(User.php)

<?php

namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Traits\EncryptableTrait;

class User extends Authenticatable {
{
    use EncryptableTrait;

    protected $table = 'users';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['role_id', 'user_type', 'first_name', 'last_name', 'email', 'password', 'is_verified', 'status'];


    protected $encryptable = [
        'first_name', 'last_name', 'email'
    ]; 

}


Here i have written encrypt and decrypt code in trait EncryptableTrait.php

<?php
namespace App\Traits;

use Illuminate\Support\Facades\Crypt;

trait EncryptableTrait {

    protected $encryptKey;

    public function getAttribute($key)
    {
        $value = parent::getAttribute($key);

        if (in_array($key, $this->encryptable) && ( ! is_null($value)))
        {
            $value = $this->deCryptData($value);
        }

        return $value;
    }

    public function setAttribute($key, $value)
    {
        if (in_array($key, $this->encryptable))
        {
            $value = $this->encryptData($value);
        }
        return parent::setAttribute($key, $value);
    }

    private function encryptData($value)
    {
        $encryptValue = '';
        $cbSrc = strlen($value);
        $encryptKey = \Config::get('app.encryption_key');
        $encryptKeySize =  strlen($encryptKey);   
        for($NdxKey = 0, $i = 0; $i < $cbSrc; $i++)
        {
            $encryptValue .= sprintf("%02X", (ord($value[$i]) ^ ord($encryptKey[$NdxKey++])) & 0xFF);
                        
            if ($NdxKey >= $encryptKeySize)
                $NdxKey = 0;
        }
        return $encryptValue;   
    }

    private function deCryptData($value)
    {
        $decryptValue = '';
        $cbSrc = strlen($value);
        $encryptKey = \Config::get('app.encryption_key');
        $encryptKeySize =  strlen($encryptKey);   
        $deVal = null;
        
        for($NdxKey = 0, $i = 0; $i < $cbSrc; $i += 2)
        {
            sscanf($value[$i] . $value[$i + 1], "%x", $deVal);
            $decryptValue .= sprintf("%c", ($deVal ^ ord($encryptKey[$NdxKey++])) & 0xFF);
            
            if ($NdxKey >= $encryptKeySize) 
                $NdxKey = 0;
        }
        return $decryptValue;   
    }

?>

Note:-You can use laravel predefined encrypt method here, but this method give you different encrypt string for same string, but the method i have used provide same encrypted value all time

in config/app.php

    'encryption_key' => env('APP_KEY'),

This APP_KEY should never change.

Thanks.

No comments:

Post a Comment