Skip to content
This repository has been archived by the owner on Jul 16, 2021. It is now read-only.

Encrypt/decrypt attributes with casts or model property #1244

Open
barryvdh opened this issue Jul 2, 2018 · 10 comments
Open

Encrypt/decrypt attributes with casts or model property #1244

barryvdh opened this issue Jul 2, 2018 · 10 comments

Comments

@barryvdh
Copy link

barryvdh commented Jul 2, 2018

To make it easier to encrypt/decrypt columns in the database, it could be built-in to the Eloquent model, similar to either the $dates attribute or the $casts properties.
Using an extra property would allow for being cast to a type after decrypting, so perhaps better.

To make it easy for users to encrypt existing data, a command could be added to encrypt data based on these columns. (eg. php artisan db:encrypt --class="App\User")

It could be done using mutators/accessors, but having this built-in could make it easier and cache objects to avoid multiple times decrypting the same value in the same request.

@Miguel-Serejo
Copy link

I like it.

We'd also need a way to re-encrypt old data with a new key/algorithm, something like php artisan db::recrypt --class="App\User" --old-key=OLD_KEY --old-algorithm=bcrypt --new-key=NEW_KEY --new-algorithm=argon2

Or perhaps a new configuration file with different encryption settings, such as:

//encryption.php
return [
  'users' => [
    'algorithm' =>  'bcrypt',
    'key' => env('USERS_BCRYPT_KEY'),
  ],
  'transactions => 
    'argon' => [
      'algorithm' => 'argon2',
      'key' => env('TRANSACTIONS_ARGON2_KEY'),
    ],
    'bcrypt' => [
      'algorithm' => 'bcrypt',
      'key' => env('TRANSACTIONS_ARGON2_KEY'),
    ],
  ],
];

which would then allow us to reference these settings:

php artisan db:encrypt --class="App\User" --config="encryption.users"

php artisan db:recrypt --class="App\Transactions" --from="encryption.transactions.bcrypt" --to="encryption.transactions.argon"

Although now that I've typed that all out, it would probably require a major rewrite of the encryption system.

@barryvdh
Copy link
Author

barryvdh commented Jul 2, 2018

Yeah that would be a bit more complicated. (re-)Encrypting the database could be as simple as getting the attributes and doing:

foreach ($attributes as $attribute) {
	try {
		// Try to decrypt it using the default encryption
		$item->{$attribute} = $user->{$attribute};
	} catch (DecryptException $e) {
		// When fails, assume it's not encrypted yet and use the raw version
		$item->{$attribute} = $item->getOriginal($attribute);
	}
}
$item->save();

@Miguel-Serejo
Copy link

Miguel-Serejo commented Jul 2, 2018

How would your code get the original value if it fails to decrypt it?
It works perfectly fine for unencrypted values, but not for values that were encrypted with an old key.

@barryvdh
Copy link
Author

barryvdh commented Jul 2, 2018

No that's what I said, that would be more complicated. I just meant that you could run the command again with additional properties encrypted, and it would encrypt the new values without breaking the existing ones.

@Miguel-Serejo
Copy link

Yes, with the current system, an extra step would be needed in the catch block to try and decrypt again with the provided old key.

Should the key:generate command be responsible for checking if there are any encrypted models that would need to be re-encrypted with the new key?

@sisve
Copy link

sisve commented Jul 3, 2018

I'm a bit worried that announcing "support for automatically encrypt and decrypt attributes" means someone will file a bug report since they cannot search the database for these fields.User::where('encrypted_field', '=', $cleartextValue)->first(). Is this out-of-scope for this issue?

@barryvdh
Copy link
Author

barryvdh commented Jul 3, 2018

Yes that is out of scope.

@sander3
Copy link

sander3 commented Jul 31, 2018

This is what I've been using so far: https://github.com/sander3/laravel-gdpr/blob/master/src/EncryptsAttributes.php
Would really like something like this to be part of the framework.

@poisa
Copy link

poisa commented Aug 7, 2018

I'm willing to create a proof-of-concept PR if there is interest in this.

@andrey-helldar
Copy link

andrey-helldar commented Dec 27, 2019

@barryvdh, if I understand your problem correctly, the changes proposed in laravel/framework#30958 will make it easy to solve.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants