Search code examples
phpmysqllaravellaravel-5laravel-encryption

can we rely on laravel encryption for future?


We are building application where we need to store a data encrypted in database and instead of using MySql AES_ENCRYPT and AES_DECRYPT we are plaining to use laravel's inbuilt encrypt & decrypt functions.

Is it will be future proof as we don't want to loose data for future updates.


Solution

  • First of all, nothing is truly "future proof." In fact, we're on the verge of current encryption being rendered obsolete by quantum computing, making all current encryption methods very much not future proof.

    Does Taylor have any plans of changing it in the foreseeable future? Maybe, maybe not, but the only real way of knowing is to ask him directly. He's quite active on Twitter and in other venues, so as far as business owners go, he's pretty approachable. He's also a generally nice person, so don't be afraid to ping him.

    But let's take a look at the code:

    public function encrypt($value, $serialize = true)
    {
        $iv = random_bytes(16);
        // First we will encrypt the value using OpenSSL. After this is encrypted we
        // will proceed to calculating a MAC for the encrypted value so that this
        // value can be verified later as not having been changed by the users.
        $value = \openssl_encrypt(
            $serialize ? serialize($value) : $value,
            $this->cipher, $this->key, 0, $iv
        );
        if ($value === false) {
            throw new EncryptException('Could not encrypt the data.');
        }
        // Once we get the encrypted value we'll go ahead and base64_encode the input
        // vector and create the MAC for the encrypted value so we can then verify
        // its authenticity. Then, we'll JSON the data into the "payload" array.
        $mac = $this->hash($iv = base64_encode($iv), $value);
        $json = json_encode(compact('iv', 'value', 'mac'));
        if (! is_string($json)) {
            throw new EncryptException('Could not encrypt the data.');
        }
        return base64_encode($json);
    }
    

    That's the main encrypt() function from master in the repository, and from the looks of it, it's not likely to be changed too much without completely rewriting it. And while Laravel doesn't really follow the SemVer versioning spec, it does generally follow an internally consistent versioning scheme, making the most likely times for it to change are at the whole number and first-decimal change (i.e. - 5.4 to 5.5 or 5.5 to 6.0).

    However, it's worth noting that it's actually accessed via contracts and the service provider pattern (so the only time the class is actually directly referenced is in its associated ServiceProvider class). This means that you can use this one for now and if a breaking change is introduced in the future, you can copy this version into your own encryption class, replace the reference in config/app.php to Illuminate\Encryption\EncryptionServiceProvider to your new encryption service provider, and you've now preserved that method and can use it throughout your application, without making any other changes to your application.

    On a bit of a side note, you can also consider writing an "encryption converter" if you find you do need to change algorithms (such as if your original algorithm is insecure) by using the old system's decrypt method to decrypt everything, then re-encrypt it all with the new system and storing it again. The application would then just use the new algorithm going forward.