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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (733)

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

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

我发现密钥(加密器的第一个参数)到达“有时”空,当然它失败了。大多数情况下,密钥是正确的,但随机密钥从EncryptionServiceProvider空到达,并轮流将其请求到应用配置。

所以对我而言,唯一的解决方案是if ($key)在EncryptionServiceProvider中添加一个Encryption构造函数,不会使用空键调用。

当然,这不是一个“clean”解决方案,也不是解释问题,但至少避免找到填充了错误的日志文件:

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文件,config,artisan新密钥生成,cache:clear,config:clear,composer更新。这东西是可以的,因为它工作99%的时间,但随机我得到的错误。

这里的后面跟踪:

[2017-01-09 10:25:40] test.ERROR:RuntimeException:唯一支持的密码是具有正确密钥长度的AES-128-CBC和AES-256-CBC。在C:\ Apache24 \ htdocs \ sph \ vendor \ laravel \ framework \ src \ Illuminate \ Encryption \ 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}  
提问于
用户回答回答于

我安装了Laravel5.3,但在那里没有找到.env文件。然后砰..。这就是问题所在。我在应用程序根目录中创建了.env文件并运行

PHP手工键:生成

在终端中,它在终端中产生64基编码字符串。将该字符串复制到.env文件中,作为

APP_Key=base 64:************************************************

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

用户回答回答于

在多线程Web服务器上使用线程安全版本的PHP而不是多进程Web服务器时会出现此问题。您可以在这里阅读有关Github问题的更多信息Github问题以及PHP错误报告。还有几个链接,但他们只是从我发布的那几个中分出来的。

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

所以,你最终会得到这样的结果:(如本期所述):

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。这也由包本身提出: phpdotenv是为开发环境而设计的,一般不应该用于生产。在生产中,应该设置实际的环境变量,以便在每个请求上加载.env文件没有开销。
  2. 切勿使用env()配置文件以外的方法,并确保缓存配置文件。通过使用此方法,环境只读一次:创建配置文件缓存时。每个实际的Web请求都会从缓存中读取数据,并且环境变量将永远不会再次被触摸。

扫码关注云+社区

领取腾讯云代金券