上面用到了一个自定义的方法hash(),我们可以看下方法的实现。
protected function hash($iv, $value)
{
// 生成签名
// 1、把随机值转为base64
// 2、使用hash_hmac生成sha256的加密值,用来验证参数是否更改。第一个参数表示加密方式,目前是使用sha256,第二个是用随机值连上加密过后的内容进行,第三个参数是上步使用的key。生成签名。
return hash_hmac('sha256', $iv.$value, $this->key); /根据随机值和内容,生成一个sha256的签名
}
以上加密共分了三大步
1、生成随机码
2、生成加密内容
3、生成签名
框架用到一个优雅的方法,使用serialize生成一个值,这个方法高雅在哪里,就是不管你得内容是数组还是字符串,都能转换成字符串。 而使用serialize和使用json_encode的区别在哪,我想最大的好处是,你所要加密的内容比较大的时候,serialize相对于要快。
另外一个地方是,框架在加密的时候使用了一个随机字符串。为什么要使用随机字符串呢,因为使用了随机字符串,使每次加密的内容都是不一样的,防止别人猜出来。
3. 分析decrypt方法
解密数据,可以说是最复杂的一块,不仅要进行数据的解密,而且还要保证数据的完整性,以及数据防篡改
public function decrypt($payload, $unserialize = true)
{
$payload = $this->getJsonPayload($payload); //把加密后的字符串转换出成数组。
$iv = base64_decode($payload['iv']); //把随机字符串进行base64解密出来
$decrypted = \openssl_decrypt( //解密数据
$payload['value'], $this->cipher, $this->key, 0, $iv
);
if ($decrypted === false) {
throw new DecryptException('Could not decrypt the data.');
}
return $unserialize ? unserialize($decrypted) : $decrypted; //把数据转换为原始数据
}
getJsonPayload方法
protected function getJsonPayload($payload)
{
$payload = json_decode(base64_decode($payload), true); //把数据转换为原来的数组形式
if (! $this->validPayload($payload)) { //验证是不是数组以及数组里有没有随机字符串,加密后的内容,签名
throw new DecryptException('The payload is invalid.');
}
if (! $this->validMac($payload)) { //验证数据是否被篡改
throw new DecryptException('The MAC is invalid.');
}
return $payload;
}
validPayload方法就不说了,比较简单和基本,重点就说说validMac验证这块,保证数据不被篡改,这是最重要的
protected function validMac(array $payload)
{
$calculated = $this->calculateMac($payload, $bytes = random_bytes(16)); //拿数据和随机值生成一个签名
return hash_equals( //比对上一步生成的签名和下面生成的签名的hash是否一样。
hash_hmac('sha256', $payload['mac'], $bytes, true), $calculated //根据原始数据里的签名在新生成一个签名
);
}
calculateMac方法是为了根据原始数据和随机值生成一个签名,然后用这签名再次生成一个签名
protected function calculateMac($payload, $bytes)
{
return hash_hmac(
'sha256', $this->hash($payload['iv'], $payload['value']), $bytes, true
);
}
以上解密共分了三大步
1、判断数据的完整性
2、判断数据的一致性
3、解密数据内容。
这个验证签名有个奇怪的地方,他并不像我们平常验证签名一样。我们平常验证签名都是,拿原始数据和随机值生成一个签名,然后拿生成的签名和原始数据的签名进行比对来判断是否有被篡改。
而框架却多了一个,他用的是,通过原始数据和随机值生成签名后,又拿这个签名生成了一个签名,而要比对的也是拿原始数据里的签名在生成一个签名,然后进行比对。目前想不出,为什么要多几步操作。
在加密的时候,我们把原始数据使用serialize转换了一下,所以我们相应的也需要使用unserialize把数据转换回来。
laravel ORM 只开启created_at的几种方法总结下面小编就为大家分享一篇laravel ORM 只开启created_at的几种方法总结,具有很好的参考价值,希望对大家有所帮助。一
通过源码解析Laravel的依赖注入这篇文章主要给大家介绍了如何通过源码解析Laravel的依赖注入的相关资料,文中通过示例代码介绍的非常详细,对大
Laravel中unique和exists验证规则的优化详解这篇文章主要给大家介绍了关于Laravel中unique和exists验证规则的优化的相关资料,文中通过示例代码介绍的非常详细,
Laravel 5.5基于内置的Auth模块实现前后台登陆详解最近在使用laravel5.5,利用其实现了一个功能,下面分享给大家,这篇文章主要给大家介绍了关于Laravel 5.5基于内置的
源码分析 Laravel 重复执行同一个队列任务的原因laravel 的队列服务对各种不同的后台队列服务提供了统一的 API,下面这篇文章通过源码分析给大家介绍了关于 Larave
关于 Laravel Redis 多个进程同时取队列问题详解这篇文章主要给大家介绍了关于 Laravel Redis 多个进程同时取队列问题的相关资料,文中通过示例代码介绍的非常详细