浅析 APP_KEY 的作用

本文翻译自 APP_KEY And You

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

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

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

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

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

当你的应用程序执行的时候,只有一个地方会用到 APP_KEY:cookies。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 无法胜任,因此我们需要使用哈希方法,具有如下的特点:

快速:计算机能够快速的生成哈希值
确定性:针对同样的输入,输出是固定的
随机性:即使只更改一位字符串,哈希之后的输出应该十分不同
唯一性:碰撞概率应该非常非常的小
难于被暴力破解: 哈希之后的值应当难以被暴力破解
你应当听说过许多的单向哈希算法,例如 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 数据表,那么上面的输出你可能会似曾相识。下面解释一下其中的含义:

$2y$ 表示我们使用了 blowfish 算法(bcrypt)
10$ 表示算法使用的 cost(值越高表示生成哈希的时间越长)
hEEF0lv4spxnvw5O4XyLZ. 表示一个 22 位的随机 “盐”
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 的更改

————————————————
原文作者:Epona
转自链接:https://learnku.com/articles/31169
版权声明:著作权归作者所有。商业转载请联系作者获得授权,非商业转载请保留以上作者信息和原文链接。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值