Encryption and decryption in Laravel 5

17,712

Solution 1

You can handle encrypted attributes with a trait (app/EncryptsAttributes.php):

namespace App;

trait EncryptsAttributes {

    public function attributesToArray() {
        $attributes = parent::attributesToArray();
        foreach($this->getEncrypts() as $key) {
            if(array_key_exists($key, $attributes)) {
                $attributes[$key] = decrypt($attributes[$key]);
            }
        }
        return $attributes;
    }

    public function getAttributeValue($key) {
        if(in_array($key, $this->getEncrypts())) {
            return decrypt($this->attributes[$key]);
        }
        return parent::getAttributeValue($key);
    }

    public function setAttribute($key, $value) {
        if(in_array($key, $this->getEncrypts())) {
            $this->attributes[$key] = encrypt($value);
        } else {
            parent::setAttribute($key, $value);
        }
        return $this;
    }

    protected function getEncrypts() {
        return property_exists($this, 'encrypts') ? $this->encrypts : [];
    }

}

Use it in your models when necessary:

class Employee extends Model {

    use EncryptsAttributes;

    protected $encrypts = ['cardNumber', 'ssn'];

}

Then you can get and set the attributes without thinking about the encryption:

$employee->ssn = '123';
{{ $employee->ssn }}

Solution 2

You could create a custom function or an accessor in your model.

Say your model is Employee and your encrypted column is ssn. You could do that:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Employee extends Model
{
    // With a function
    public function decryptSsn()
    {
        return decrypt($this->attributes['ssn']);
    }

    // With an accessor
    public function getDecryptedSsnAttribute()
    {
        return decrypt($this->attributes['ssn']);
    }
}

In case you go with function, you'd call it like this:

$employee->decryptSsn();

And if you go with an accessor, you would call it like this:

$employee->decrypted_ssn;
Share:
17,712
Matthew
Author by

Matthew

Almost always playing around in the depths of archives, thumbing through one document at a time and the rest of the time, building drupal sites. :)

Updated on June 12, 2022

Comments

  • Matthew
    Matthew almost 2 years

    I have been looking for ideas on encrypting and decrypting values in Laravel (like VIN Numbers, Employee ID Card Numbers, Social Security Numbers, etc.) and recently found this on the Laravel website: https://laravel.com/docs/5.6/encryption

    My question is, how would I print the decrypted values on a blade template? I could see going through the controller and setting a variable and then printing it to a Blade, but I was curious as to how I would also print a decrypted value to an index? Like so...

    @foreach($employees as $employee)
    {{$employee->decrypted value somehow}}
    {{$employee->name}}
    @endforeach
    
  • ceejayoz
    ceejayoz about 6 years
    This seems to be overcomplicating things a little when a simple {{ decrypt($employee->ssn) }} in the view would do.
  • DevK
    DevK about 6 years
    That would work too, yes. I'd suggest going with a function/accessor for easier maintenance
  • fubar
    fubar about 6 years
    I would disagree that having a separate function or accessor for each and every encrypted attribute is easily maintainable. I'd be more inclined to inherit a function (class or trait) which takes the attribute name, and handles the decryption instead.
  • fubar
    fubar about 6 years
    So if you plan to print it multiple times within the same request cycle, the accessor is better. - how is it better? The decrypted value isn't cached. So what's the difference?
  • DevK
    DevK about 6 years
    @fubar You're right about the decrypted value not being cached. I thought it gets appended to $attributes array the first time it's called and gets called from there from thereon. Tested and I was wrong. As for function being more maintainable, yes having a trait or appending another type to $casts would be even more maintainable. But having decrypt($m->ssn) in many views will likely happen and this is step 1 to easier maintenance.
  • Tpojka
    Tpojka about 6 years
    Totally unneeded function.
  • narayansharma91
    narayansharma91 about 6 years
    That will only use full when you are using same logic at multiple times and you want to modify decrypt and encrypt logic globally. Other wise you have to modify to multiple location. It is handy just change on one place will select to all over the application.
  • Tpojka
    Tpojka about 6 years
    What is the gain of using decryptText($text) instead of decrypt($text)?
  • narayansharma91
    narayansharma91 about 6 years
    function decryptText($text) { return decrypt($text);// if you have multiple logic here like //decrypt(anotherfunction(anotherfunction($text))) like so... }
  • Tpojka
    Tpojka about 6 years
    It's called code bloat what you did there.
  • ceejayoz
    ceejayoz about 6 years
    "Yo dawg, I heard you like helpers, so I put a helper in your helper so you can helper while you helper..."
  • Rahul Tathod
    Rahul Tathod almost 6 years
    hi i implement the same and its working with getattribute and setattribute but didnt get why use attributesToArray
  • Jonas Staudenmeir
    Jonas Staudenmeir almost 6 years
    attributesToArray() is necessary for $model->toArray() and $model->toJson().