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。

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 1

为什么这里不用 安全 base64 ,就是将 + / = 替换?

5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!