【转载】Laravel中APP_KEY的作用

转自:https://learnku.com/articles/31169

可能每个 Laravel 开发者新建或者克隆一个 Laravel 程序的时候,composer install 之后最可能以及最重要的的第一步操作就是生成 APP_KEY

在这篇文章中我们会讨论 APP_KEY 能做的和不能做的,有些人会把用户密码的哈希处理与 APP_KEY 相关联(实际上它们毫无关联)。

什么是 APP_KEY

每一个 Laravel 程序都会生成一个随机的 32 位长度的字符串存储在.env 文件中的 APP_KEY 键值中,当我们新建 Laravel 项目的时候会自动为你创建一个,只有在克隆的时候你才有可能发现它没有被设定。

你可能看到过下面的错误,说明 APP_KEY 没有设定

app_key error

你可以自己手动生成或者使用 php artisan key:generate 来进行创建 APP_KEY

当你的应用程序执行的时候,只有一个地方会用到 APP_KEYcookies。Laravel 使用它来加密所有的 cookies,在将 cookie 返回给用户之前 Laravel 会对 cookie 进行加密,然后再返回给用户,这样客户端就无法自己修改 cookie 来伪装成管理员或者其他用户了。

所以的加密和解密都在 Encrypter中进行处理,其中主要使用了 [openssl_encrypt](https://secure.php.net/manual/en/function.openssl-encrypt.php) 进行加密。

有很多用户都会有一个误解,那就是 APP_KEY 是用来处理用户哈希密码的。事实上不是这样的。Laravel 的密码使用了 Hash::make() 或者 bcrypt() 来进行哈希处理,其中并没有用到 APP_KEY

加密 VS 哈希

在 Laravel 中有两个主要的加密 Facade,分别是 Crypt(对称加密) 和 Hash(单向加密哈希)。密码是哈希,而 cookie 则是对称加密

对称加密

假设我想发送一条加密的信息给我的好友 A。我们商议好了一个用于加密和解密的 key:

$key = "dont-panic";

当我想要发送一条只有上面的 key 能解锁的信息时,我们可以使用 openssl_encrypt()(Laravel 的 Crypt 也是使用的这个方法),具体如下:

$message = "So long and thanks for all the fish";
$key = "dont-panic";
$cipher = "AES-256-CBC";
echo openssl_encrypt($message, $cipher, $key);

// JJEK8L4G3BCfY0evXDRxUke2zqAzq6i7wL/Px4SjaEHXqt3x7hsj4+PhVQaH4ujX

此时,你就可以把这段加密的代码发送给 A,然后他可以进行解密了。

$secret = "JJEK8L4G3BCfY0evXDRxUke2zqAzq6i7wL/Px4SjaEHXqt3x7hsj4+PhVQaH4ujX";
$key = "dont-panic";
$cipher = "AES-256-CBC";
echo openssl_decrypt($secret, $cipher, $key);

// So long and thanks for all the fish

Laravel 的 cookie 加密解密也是同理,只不过 key 使用的是 APP_KEY

单向哈希

当我们使用密码的时候,我们应当从不使用对称加密的方法,来避免用户可能解密密码。这表示 Crypt 无法胜任,因此我们需要使用哈希方法,具有如下的特点:

  1. 快速:计算机能够快速的生成哈希值
  2. 确定性:针对同样的输入,输出是固定的
  3. 随机性:即使只更改一位字符串,哈希之后的输出应该十分不同
  4. 唯一性:碰撞概率应该非常非常的小
  5. 难于被暴力破解: 哈希之后的值应当难以被暴力破解

你应当听说过许多的单向哈希算法,例如 md5 和 SHA-1。在 Laravel 中使用了 PHP 的原生方法 password_hash(),它使用的哈希算法叫 bcrypt

use Illuminate\Support\Facades\Hash;

$password = "dont-panic";
echo Hash::make($password);

// $2y$10$hEEF0lv4spxnvw5O4XyLZ.QjCE1tCu8HjMpWhmCS89J0EcSW0XELu

如果你曾经查看过 users 数据表,那么上面的输出你可能会似曾相识。下面解释一下其中的含义:

  1. $2y$ 表示我们使用了 blowfish 算法(bcrypt)
  2. 10$ 表示算法使用的 cost(值越高表示生成哈希的时间越长)
  3. hEEF0lv4spxnvw5O4XyLZ. 表示一个 22 位的随机 “盐”
  4. QjCE1tCu8HjMpWhmCS89J0EcSW0XELu 哈希结果

由于这是一个单向哈希,因此我们无法进行解密,我们能做的只是去验证其是否匹配。

use Illuminate\Support\Facades\Hash;

$input = request()->get('password'); // "dont-panic"
$hash = '$2y$10$hEEF0lv4spxnvw5O4XyLZ.QjCE1tCu8HjMpWhmCS89J0EcSW0XELu';
return Hash::check($input, $hash);

// true

因此我们可以看到,在对称加密中我们使用到了 APP_KEY,而在密码哈希的时候我们是不需要使用它的。

总结

  • 更改 APP_KEY 不会使用户的密码失效
  • 更改 APP_KEY 会使 session 和 cookie 失效,导致当前已登录用户退出登录
  • 不要害怕你的 APP_KEY
  • 如果你在其他地方使用了 Laravel 的加密方法,那么你需要制定一个计划来应对 APP_KEY 的更改
点赞
  1. PokerPhantom说道:
    Google Chrome Windows 10
    https://t.me/officials_pokerdom/3448
  2. ChipWhisperer说道:
    Google Chrome Windows 10
    https://t.me/s/ezcash_officials
  3. HighRollerMage说道:
    Google Chrome Windows 10
    http://images.google.ki/url?q=https://t.me/officials_7k/289
  4. ChipWhisperer说道:
    Google Chrome Windows 10
    В джунглях игр, где всякий сайт пытается заманить гарантиями быстрых призов, официальные казино онлайн рейтинг является именно той путеводителем, что проводит сквозь дебри обмана. Для ветеранов да начинающих, кто пресытился от фальшивых заверений, такой помощник, чтоб ощутить реальную rtp, будто ощущение ценной фишки на руке. Минус пустой ерунды, только проверенные клубы, где rtp не лишь цифра, а реальная везение.Подобрано на основе гугловых запросов, словно ловушка, что захватывает наиболее горячие тренды в рунете. В нём нет пространства для шаблонных приёмов, каждый пункт как карта на игре, в котором блеф раскрывается сразу. Профи видят: на России манера разговора на подтекстом, где ирония скрывается под совет, помогает избежать ловушек.На https://www.provenexpert.com/don8play такой список лежит словно готовая карта, подготовленный к раздаче. Загляни, коли хочешь увидеть пульс настоящей ставки, обходя обмана и неудач. Тем тех любит ощущение удачи, он будто взять фишки в пальцах, минуя смотреть по экран.

发表回复

电子邮件地址不会被公开。必填项已用 * 标注