When to Generate a New Application Key in Laravel

When to generate a new Application Key in Laravel?

php artisan key:generate is a command that sets the APP_KEY value in your .env file. By default, this command is run following a composer create-project laravel/laravel command. If you use a version control system like git to manage your project for development, calling git push ... will push a copy of your Laravel project to wherever it is going, but will not include your .env file. Therefore, if someone clones your project using git clone ... they will have to manually enter php artisan key:generate for their app to function correctly.

So, TL:DR the only time you need to call php artisan key:generate is following a clone of a pre-created Laravel project.

Side note: If you try to run a Laravel project with your APP_KEY set to SomeRandomString (which is the default in your .env.example file, you will actually get an error:

No supported encrypter found. The cipher and / or key length are invalid.

Is it necessary to execute php artisan key:generate command after installation of laravel 5.7

php artisan key:generate

This command sets the APP_KEY value in your .env file.

If you create a project with composer it'll generated default with project.

composer create-project laravel/laravel

If you clone project using git clone some folder is ignored by git so you might not get env file as well as vendor folder. Therefore, they will have to manually enter php artisan key:generate for their app to function correctly.

So, TL:DR the only time you need to call php artisan key:generate is following a clone of a pre-created Laravel project.

Note: If you try to run a Laravel project with your APP_KEY set to SomeRandomString (which is the default in your .env.example file, you will actually get an error:

No supported encrypter found. The cipher and / or key length are invalid.

Laravel 5 Application Key

This line in your app.php, 'key' => env('APP_KEY', 'SomeRandomString'),, is saying that the key for your application can be found in your .env file on the line APP_KEY.

Basically it tells Laravel to look for the key in the .env file first and if there isn't one there then to use 'SomeRandomString'.

When you use the php artisan key:generate it will generate the new key to your .env file and not the app.php file.

As kotapeter said, your .env will be inside your root Laravel directory and may be hidden; xampp/htdocs/laravel/blog

php artisan key:generate gives a No application encryption key has been specified. error

php artisan key:generate needs an existing key to work. Fill the APP_KEY with 32 characters and rerun the command to make it work.

Edit: A newly created app via laravel new with a deleted APP_KEY can run php artisan key:generate without issue for some reason.

Edit a year later:
The real problems lays in 2 added provider services. The boot() functions are badly written which causes the problem. Still not exactly sure why it doesn't work but I'll try and figure it out for somebody who may have the same problem later.

The two files in question

<?php

namespace App\Providers;

use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Routing\ResponseFactory;

class ResponseServiceProvider extends ServiceProvider
{
public function boot(ResponseFactory $factory){
parent::boot();
$factory->macro('api', function ($data=null, $code=null, $message=null) use ($factory) {
$customFormat = [
'status' => 'ok',
'code' => $code ? $code : 200,
'message' => $message ? $message : null,
'data' => $data
];

if ($data instanceof LengthAwarePaginator){
$paginationData = $data->toArray();
$pagination = isset($paginationData['current_page']) ? [
"total" => $paginationData['total'],
"per_page" => (int) $paginationData['per_page'],
"current_page" => $paginationData['current_page'],
"last_page" => $paginationData['last_page'],
"next_page_url" => $paginationData['next_page_url'],
"prev_page_url" => $paginationData['prev_page_url'],
"from" => $paginationData['from'],
"to" => $paginationData['to']
] : null;

if ($pagination){
$customFormat['pagination'] = $pagination;
$customFormat['data'] = $paginationData['data'];
}
}

return $factory->make($customFormat);
});
}

public function register(){
//
}
}
<?php

namespace App\Providers;

use App\Http\Controllers\Auth\SocialTokenGrant;
use Laravel\Passport\Bridge\RefreshTokenRepository;
use Laravel\Passport\Bridge\UserRepository;
use Laravel\Passport\Passport;
use Laravel\Passport\PassportServiceProvider;
use League\OAuth2\Server\AuthorizationServer;

/**
* Class CustomQueueServiceProvider
*
* @package App\Providers
*/
class SocialGrantProvider extends PassportServiceProvider{
/**
// * Bootstrap any application services.
// *
// * @return void
// */
public function boot(){
parent::boot();
app(AuthorizationServer::class)->enableGrantType($this->makeSocialRequestGrant(), Passport::tokensExpireIn());
}

/**
* Register the service provider.
*
* @return void
*/
public function register(){
}

/**
* Create and configure a SocialTokenGrant based on Password grant instance.
*
* @return SocialTokenGrant
*/
protected function makeSocialRequestGrant(){
$grant = new SocialTokenGrant(
$this->app->make(UserRepository::class),
$this->app->make(RefreshTokenRepository::class)
);
$grant->setRefreshTokenTTL(Passport::refreshTokensExpireIn());
return $grant;
}
}

What is the significance of Application key in a Laravel Application?

As we can see its used in EncryptionServiceProvider:

public function register()
{
$this->app->singleton('encrypter', function ($app) {
$config = $app->make('config')->get('app');

// If the key starts with "base64:", we will need to decode the key before handing
// it off to the encrypter. Keys may be base-64 encoded for presentation and we
// want to make sure to convert them back to the raw bytes before encrypting.
if (Str::startsWith($key = $this->key($config), 'base64:')) {
$key = base64_decode(substr($key, 7));
}

return new Encrypter($key, $config['cipher']);
});
}

So every component that uses encryption: session, encryption (user scope), csrf token benefit from the app_key.


Rest of the questions can be answered by "how encryption" (AES) works, just open up Encrypter.php, and confirm that Laravel uses AES under the hood and encodes the result to base64.

Further more we can see how its all done by using tinker:

➜  laravel git:(staging) ✗ art tinker
Psy Shell v0.8.17 (PHP 7.1.14 — cli) by Justin Hileman
>>> encrypt('Hello World!')
=> "eyJpdiI6ImgzK08zSDQyMUE1T1NMVThERjQzdEE9PSIsInZhbHVlIjoiYzlZTk1td0JJZGtrS2luMlo0QzdGcVpKdTEzTWsxeFB6ME5pT1NmaGlQaz0iLCJtYWMiOiI3YTAzY2IxZjBiM2IyNDZiYzljZGJjNTczYzA3MGRjN2U3ZmFkMTVmMWRhMjcwMTRlODk5YTg5ZmM2YjBjMGNlIn0="

Note: I used this key: base64:Qc25VgXJ8CEkp790nqF+eEocRk1o7Yp0lM1jWPUuocQ= to encrypt Hello World!

After decoding the result we get (you can try decode your own cookie with session):

{"iv":"h3+O3H421A5OSLU8DF43tA==","value":"c9YNMmwBIdkkKin2Z4C7FqZJu13Mk1xPz0NiOSfhiPk=","mac":"7a03cb1f0b3b246bc9cdbc573c070dc7e7fad15f1da27014e899a89fc6b0c0ce"}

to understand above json (iv, value, mac) you need to understand AES:

  • https://en.wikipedia.org/wiki/Advanced_Encryption_Standard

Best practices for application key

  • do store it in .env file only
  • do not store it in app.php, in fact in any git tracked file
  • do not change it unless you really want to

    • invalidate sessions/cookies (user logout)
    • invalidate password reset tokens
    • invalidate signed urls

Obvious Note: Changing application key has no effect on hashed passwords since hashing algorithms do not require encryption keys.

Is it ok if more than one developer use the same APP_KEY in Laravel for local development?

It is OK.

Since Laravel uses APP_KEY for encrypting cookies (I've just learnt that) including session cookie, it doesn't matter if the developers are using the same APP_KEY in their local environment.

On the other hand, it is important to produce new APP_KEY for the production environment and even change it regularly.

My resource: https://tighten.co/blog/app-key-and-you/

Laravel's application key - what it is and how does it work?

APP_KEY is used for encryption and not hashing. Every Data you encrypt in your application is using APP_KEY behind the scene. Do remember that encrypted data can be decrypted but hashed data cannot be decrypted.

A common misconception of APP_KEY is that it is related to Password hashing, the truth is it's not. and here is the proof.

taylor's tweet

You can see in the above tweet that APP_KEY has nothing to do with HASHED data

Problem with generating and using application key within a CI Job

The Problem was that phpunit automatically uses the testing environment (APP_ENV must be testing) if it exists.

php artisan key:generate --env=testing did solve the problem.

Just in case anybody else runs into this problem.



Related Topics



Leave a reply



Submit