People often think APP_KEY is used to hash passwords, it isn't. Here's what this key is used for:
- Encrypting cookies.
- Creating the signature for signed URLs and queued closures.
- Encrypting values using the encrypt() and decrypt() helpers.
You should deal with the APP_KEY
as a secret. If you think it has been exposed, you MUST change it. However, make sure you re-encrypt any stored encrypted values. Also understand that there'll be some side effects:
- All previously queued closures won't be able to run.
- All users will be logged out and all token values will be lost.
- All previously created signed routes won't work.
You can override the encrypter in your app to use an old key if it failed to decrypt a value with the new key. That way you can keep your app running fully after rotation until all the values are re-encrypted.
<?php
namespace App\Providers;
use App\Encrypter;
use Illuminate\Support\Str;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$this->app->singleton('encrypter', function($app){
$config = $app->make('config')->get('app');
if (Str::startsWith($key = $config['key'], 'base64:')) {
$key = base64_decode(substr($key, 7));
}
return new Encrypter($key, $config['cipher']);
});
}
}
<?php
namespace App;
use Illuminate\Support\Str;
class Encrypter extends \Illuminate\Encryption\Encrypter
{
/**
* Decrypt the given value.
*
* @param string $payload
* @param bool $unserialize
* @return mixed
*
* @throws \Illuminate\Contracts\Encryption\DecryptException
*/
public function decrypt($payload, $unserialize = true)
{
try{
return parent::decrypt($payload, $unserialize);
}catch(\Throwable $e){
$currentKey = $this->key;
$this->key = Str::startsWith(config('app.old_key'), 'base64:')
? base64_decode(substr(config('app.old_key'), 7))
: config('app.old_key');
return tap(parent::decrypt($payload, $unserialize), function () use ($currentKey) {
$this->key = $currentKey;
});
}
}
}
Top comments (2)
Hello,
I need to perform client side encryption but the APP_KEY must be kept by the client on his server ! It's possible to externalize the APP_KEY ?
thank you
Though it's late I would like to add here. You can use Doppler service for that.