laravel / ideas

Issues board used for Laravel internals discussions.
938 stars 28 forks source link

[Encryption] Encryption drivers & custom asymmetric encryption #2563

Closed rennokki closed 3 years ago

rennokki commented 3 years ago

Motivation

Lately, I've been working with Laravel's Encryption module and I've found out that there are only two ciphers available. What intrigued me is that is a bit odd the way you can create your own encryptor.

$encrypter = new Encrypter($key, config('app.cipher'));

$encryptedString = $encrypter->encryptString('...');

What I was thinking about is that perhaps the way mailers, databases, queues, etc. work, a driver-powered Encryption module can exist and it can be extended.

Leveraging RSA (and Asymmetric Keys)

For example, now I'm in a situation where I decided to use the RSA algorithm from phpseclib in order to be able to encrypt and decrypt sensitive data while the Encrypt module is simple yet unable to provide asymmetric encryption which is way better than the random bytes-generated symmetric key.

This can also be put into practice better for the frontend apps too, although the following example might be just pure bananza. The current way of sending login information (or any other sensitive information) is done in plaintext and it's SSL cert's job to make sure nobody can read the form data at the network level.

Just like in an APP_KEY fashion, the project can generate a pair of public/secret keys instead of a base64-encoded, random bytes-based key and can give the frontend apps that public key to encrypt specific bits of data (passwords, sensitive info mostly) via an endpoint. Whenever the frontend app (i.e. Axios) calls on endpoints with that encrypted information, the server can easily decrypt those bits because the private key hasn't been exposed.

Again, I'm not sure if that's over-engineering, but it looks better.

Real Life Usage

We will just assume a simple POST /login example:

  1. Client requests public key at GET /public-key.
  2. It uses that key to encrypt specific bits of information (in this example, the password field)
  3. Sends the form in plain but with the encrypted bits ({ username: 'johndoe', password: 'base64-encrypted-password' }) to POST /login
  4. The server/app has a validation rule on the password field that automatically decrypts it with the private key (which exists in /storage for example)

Downsides

The current downside I can think of is the need of rotating the public key constantly for security purposes. I'm invoking here a discussion.

tpetry commented 3 years ago

Which security benefit is this complexity bringing to applications? You are simply reinventing a worse implementation of tls.

rennokki commented 3 years ago

Storing fields in the database that need to be encrypted, for example. In case of a data breach, the encrypted data is useless. Having TLS solves just encrypting the data in transit between the server and the frontend, but having an additional crypto layer is going to fix use cases where you want sensitive data to be securely stored.

tpetry commented 3 years ago

You are now describing a conpletely different use case. Encrypting database json fields is already solved, it‘s using symmetric encryption which hqs the same security semantics like asymmetric encryption for this usecase as the laravel application does need to have the public and private key.