Laravel 系统加密探究

原理:laravel 的加密器使用 OpenSSL 提供的 AES-256 和 AES-128 加密 (默认采用 AES-128),并且所有的加密值都是采用消息授权码(MAC)进行签名。

在使用 Laravel 的加密器之前,必须在配置文件 config/app.php 中设置 key 选项为 32 位随机字符串。可以使用 php artisan key:generate 命令来生成这个 key,该 Artisan 命令会使用 PHP 的安全随机字节生成器来构建 key 的值。如果这个值没有被设置,所有 Laravel 加密过的值都是不安全的。

laravel 当中的加密有 encrypt , 相对解密函数是 decrypt。还有一组便是 encryptString 和 decryptString。

encrypt 和 decrypt 加密的值会经过序列化处理,而 encryptString 和 decryptString 处理的值不经过序列化处理。

平时,我们使用只需要 $a = encrypt ('abc'),decrypt ($a), 只不过,decrypt 如果是在不同环境下,会爆出 invalid mac , 所以,我们必须 try 并且 catch 执行。

先来解释一波:这里的 MAC 是不是我们电脑当中的 MAC 尼,最开始我也有这样的疑惑。实际查看其中的源码之后,我发现不是的。

file

分析一波源码:

1.$iv = random_bytes (openssl_cipher_iv_length ($this->cipher)); 根据 cipher 的生成相对应长度的
字符,这里默认生成 16 位。不知道 cipher 的可以去 config/app.php 查看。'cipher' => 'AES-256-CBC',
为什么是 16 位或者 32 位尼,看这里的 supported

file
2. 使用 openssl_encrypt 把数据生成一个加密的数据
$value = \openssl_encrypt(
$serialize ? serialize($value) : $value,
$this->cipher, $this->key, 0, $iv
);
3. 先对 IV 进行 base64 转码,然后根据 iv base64 对加密数据进行 hash, 生成 MAC 值,
$mac = $this->hash($iv = base64_encode($iv), $value);

4. 对这里的 IV, 加密值,以及 MAC 值转换成 json.
$json = json_encode(compact('iv', 'value', 'mac'));
基本的东西讲到这里,那么我们是如何跨不同主机进行加密解密尼,按照上面的我们知道了,laravel 的加密会用到 APP_KEY, 难不成我们要使多个项目的值是一样的吗。这里我们可以观看源码,已解决其中的疑惑。

位置在  Illuminate\Encryption\Encrypter

file

结合图 1 和 图 2,我们可以发现类进行初始化的时候,先是将赋值 key, 那么,这个 key 其实就是加密的关键,如果我们平时直接使用 encrypt 这种调用的话,那么便是使用的是项目当中的 APP_KEY。其实,于是这里,我们可以调用加密函数便可以达到跨系统加解密:

这里,我们再分析下,laravel 当中的解密文件主要是两个

file
file

在 EncryptionServiceProvider 当中主要做的是从 config/app.php 当中拿出 key,并且去掉前面的 base64:,并且进行 base64_decode 解码。

加密:

file
解密:

file

如此,我们便可在不同的项目中定义 key 值就可以达到为跨项目加密和解密了。这里使用的时候如是使用的 AES-128,那么请传入 16 为长度的 key,如果是 AES-256, 请传入 32 长度的 key。

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。