Random RuntimeException:唯一支持的密码是AES-128-CBC和AES-256-CBC,密钥长度正确

时间:2017-01-09 15:44:08

标签: php laravel

我对 Laravel 5.3 (在Windows服务器上)有同样的问题。我做了所有可能的尝试:检查.env文件,配置,artisan新密钥生成,缓存:清除,配置:清除,作曲家更新,但问题随机持续存在。

请注意,完全相同版本的apache,mysql,php的相同代码在Mac OS上不会产生此问题。

我发现密钥(加密器约束器的第一个参数)到达"有时"空的,当然它失败了。大多数情况下密钥是正确的,但随机密钥从EncryptionServiceProvider到达为空,然后再将其询问应用程序配置。

因此,对我有用的唯一解决方案是在EncryptionServiceProvider中添加if ($key),以便加密构造函数不会被空键调用。

当然不是"清洁"解决方案也没解释问题,但至少避免找到填充错误的日志文件:

  

RuntimeException:唯一支持的密码是AES-128-CBC和   AES-256-CBC和页面显示正确。

如果这是一个Laravel错误,我不知道,但当然如果有人能够解释这一点,我会更乐意知道。

以下是我修改过的课程:我刚刚在if ($key)之前添加了new Encrypter行:

class EncryptionServiceProvider extends ServiceProvider
{
    /**
     * Register the service provider.
     *
     * @return void
     */
    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 = $config['key'], 'base64:')) {
                $key = base64_decode(substr($key, 7));
            }
        if ($key)
            return new Encrypter($key, $config['cipher']);
        });
    }
}

更多详细信息和回溯日志:

当然,正如我写的那样,我检查了.env文件,配置,artisan新密钥生成,缓存:清除,配置:清除,编写器更新。 这个东西还可以,因为它可以在99%的时间内正常工作,但随机我会收到错误。

这里的后面跟踪:

  

[2017-01-09 10:25:40] test.ERROR:RuntimeException:唯一支持   密码是AES-128-CBC和AES-256-CBC,密钥长度正确。   在   C:\ Apache24 \ htdocs中\ SPH \厂商\ laravel \框架\ SRC \照亮\加密\ Encrypter.php:43

堆栈追踪:

#0 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Encryption\EncryptionServiceProvider.php(27): Illuminate\Encryption\Encrypter->__construct('', 'AES-256-CBC')
#1 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Container\Container.php(746): Illuminate\Encryption\EncryptionServiceProvider->Illuminate\Encryption\{closure}(Object(Illuminate\Foundation\Application), Array)
#2 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Container\Container.php(644): Illuminate\Container\Container->build(Object(Closure), Array)
#3 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Foundation\Application.php(709): Illuminate\Container\Container->make('encrypter', Array)
#4 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Container\Container.php(864): Illuminate\Foundation\Application->make('encrypter')
#5 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Container\Container.php(819): Illuminate\Container\Container->resolveClass(Object(ReflectionParameter))
#6 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Container\Container.php(788): Illuminate\Container\Container->getDependencies(Array, Array)
#7 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Container\Container.php(644): Illuminate\Container\Container->build('App\\Http\\Middle...', Array)
#8 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Foundation\Application.php(709): Illuminate\Container\Container->make('App\\Http\\Middle...', Array)
#9 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(127): Illuminate\Foundation\Application->make('App\\Http\\Middle...')
#10 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php(33): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#11 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\View\Middleware\ShareErrorsFromSession.php(49): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#12 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(137): Illuminate\View\Middleware\ShareErrorsFromSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#13 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php(33): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#14 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Session\Middleware\StartSession.php(64): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#15 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(137): Illuminate\Session\Middleware\StartSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#16 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php(33): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#17 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse.php(37): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#18 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(137): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle(Object(Illuminate\Http\Request), Object(Closure))
#19 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php(33): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#20 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(104): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#21 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Routing\Router.php(655): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#22 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Routing\Router.php(629): Illuminate\Routing\Router->runRouteWithinStack(Object(Illuminate\Routing\Route), Object(Illuminate\Http\Request))
#23 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Routing\Router.php(607): Illuminate\Routing\Router->dispatchToRoute(Object(Illuminate\Http\Request))
#24 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(268): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request))
#25 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php(53): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}(Object(Illuminate\Http\Request))
#26 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode.php(46): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#27 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(137): Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode->handle(Object(Illuminate\Http\Request), Object(Closure))
#28 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php(33): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#29 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php(104): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request))
#30 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(150): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#31 C:\Apache24\htdocs\sph\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php(117): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request))
#32 C:\Apache24\htdocs\sph\public\index.php(53): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request))
#33 {main}  

4 个答案:

答案 0 :(得分:10)

在多线程Web服务器上使用线程安全版本的PHP而不是多进程Web服务器时会出现此问题。您可以在Github issue hereGithub issue herePHP bug report here上详细了解该问题。还有一些链接,但它们只是从我发布的那些链接中分离出来。

基本要点是,使用多线程Web服务器,您只需一个处理多个线程的进程。但是,putenv() / getenv()方法不是线程安全的,并且在进程级别更改环境变量,因此该进程下的所有线程都会受到影响。

所以,你最终会得到这样的东西:(如this issue中所述):

Request 1: {starts --- loads env --- work --- finishes}
Request 2:                             {starts ----- loads env --- work --- finishes}

因此,请求1进入,加载环境,并开始工作。当请求1正在工作时,请求2进入并在另一个线程上启动。在请求2读取环境变量之前,请求1完成,PHP清除由putenv()设置的所有变量。现在,请求2尝试读取环境,但得到null,因为变量在请求1完成时被清除。

可以通过两种方式缓解此问题:

  1. 请勿在生产中使用.env文件。直接设置环境变量,并禁用phpdotenv。 package itself

    也提出了这一点
      

    phpdotenv适用于开发环境,通常不应用于生产环境。在生产中,应该设置实际的环境变量,这样就不会在每个请求上加载.env文件。

  2. 切勿在配置文件之外使用env()方法,并确保缓存配置文件。通过使用此方法,环境将被读取一次:创建配置文件缓存时。每个实际的Web请求都将从缓存中读取数据,并且永远不会再次触及环境变量。

答案 1 :(得分:0)

APP_KEY密码,如果选择AES-256-CBC,则长度必须为32个字符。

'key' => env('APP_KEY')

'cipher' => 'AES-256-CBC'

APP_KEY=base64:iT7PDx7j8yKVTj0AW81vTnEQmqLwnVfW => 32个字符

答案 2 :(得分:-1)

我安装了Laravel 5.3,但我没有在那里找到.env文件。繁荣......这就是问题所在。我在应用程序的根目录中创建了.env文件并运行了

  

php artisan key:generate

在终端中

并在终端中生成base 64编码的字符串。将该字符串复制到.env文件中

  

APP_KEY = BASE64:********** *****

其中****是生成编码的字符串。再次运行应用程序,它应该可以工作。

答案 3 :(得分:-3)

这很简单,将APP_KEY.env文件复制到config/app.php -> key或运行以下命令:

php artisan key:generate