菜单

Laravel中encrypt和decrypt的兑现情势_php实例_脚本之家

2020年2月6日 - 澳门太阳娱乐手机登录

前言

Laravel 的加密机制使用 OpenSSL 提供 AES-256 和 AES-128
的加密,本文将详细介绍有关Laravel中encrypt和decrypt的达成,分享出去供我们参考学习,上面话相当少说了,来一块看看详细的介绍吧。

1. 利用方式

率先是调换秘钥。要索要在.env目录里提供APP_KEY,那一个只要未有的话,能够通过命令php artisan key:generate变化,也能够慈善设置。生成后例子应该是这般的

APP_KEY=base64:5BM1BXGOBrGeeqJMAWJZSzyzh5yPcCGOcOGPtUij65g=

在文书配置加密key和加密算法,在config/app.php的目录里有配备

$ 'key' => env, 'cipher' => 'AES-256-CBC',

接收方式,在laravel里已经有应用办法了,这里就不在过多的说了。重要运用的多少个方法,贰个是encrypt的加密,一个是decrypt的解密

2. 追寻加密解密的文本

兑现情势的职分是在vendor/illuminate/encryption/的目录下开掘多个公文,二个是Encryption瑟维斯Provider其它一个是Encrypter

3. 分析EncryptionServiceProvider文件

 public function register() { $this->app->singleton('encrypter', function  { $config = $app->make; //从config/app.php里拿到配置文件 if (Str::startsWith($key = $config['key'], 'base64:')) { //分析配置文件里的key里面有没有带'base64' $key = base64_decode; //如果有的话,把key前面的base64:给取消,并且解析出原来的字符串 } return new Encrypter($key, $config['cipher']); //实例化Encrypte类,注入到框架里 }); }

其一文件没太多东西,然而通过这么些大家可以看看,其实在安顿文件的,大家能一向写key,并且前边不带base64也是足以解析。也就是省几步操作

除此以外,在实例化类的时候,必要传入key以至加密办法

4. 分析Encrypter文件

1. 分析__construct,在实例化早先施行

 public function __construct($key, $cipher = 'AES-128-CBC') { $key =  $key; //把key转换为字符串 if (static::supported { //调用一个自定义的方法,用来判断加密方式和要求的key长度是否一样 $this->key = $key; $this->cipher = $cipher; } else { throw new RuntimeException('The only supported ciphers are AES-128-CBC and AES-256-CBC with the correct key lengths.'); } }

上边包车型客车秘技,首若是用来推断加密方法和传的key的长短是或不是同样,因为分化的加密方法,必要的相应的key的长短也会有供给的,具体种种加密方法供给key的尺寸能够搜索对应的文书档案

 public static function supported { $length = mb_strlen; //判断key的字符的长度,按照8bit位的方式计算字符长度 return ($cipher === 'AES-128-CBC' && $length === 16) || ($cipher === 'AES-256-CBC' && $length === 32); //编码格式为AES128的要求字符长度为16。编码格式为AES256的要求字符长度为32位 }

地点这一个法子表现了三个小心的地点,用了mb_strlen方法,况兼必要测算长度是比照8bit位来计算的。那样的补益是,不管是在哪个种类操作系统,计算的长短都以同等的。

因而那一个思量到分化操作系统的景色,不会情不自禁加密辈出难题的情状。

2. 分析encrypt方法

 public function encrypt($value, $serialize = true) { $iv = random_bytes; //生成一个16位的随机字符串 // 使用openssl_encrypt把数据生成一个加密的数据 // 1、判断需要不需要生成一个可存储表示的值,这样做是为了不管你的数据是数组还是字符串都能给你转成一个字符串,不至于在判断你传过来的数据是数组还是字符串了。 // 2、使用openssl_encrypt。第一个参数是传入数据,第二个参数是传入加密方式,目前使用AES-256-CBC的加密方式,第三个参数是,返回加密后的原始数据,还是把加密的数据在经过一次base64的编码,0的话表示base64位数据。第四个参数是项量,这个参数传入随机数,是为了在加密数据的时候每次的加密数据都不一样。 $value = openssl_encrypt( $serialize ? serialize : $value, $this->cipher, $this->key, 0, $iv ); //使用AES256加密内容 if  { throw new EncryptException('Could not encrypt the data.'); } $mac = $this->hash($iv = base64_encode; //生成一个签名,用来保证内容参数没有被更改 $json = json_encode(compact); //把随机码,加密内容,已经签名,组成数组,并转成json格式 if  { throw new EncryptException('Could not encrypt the data.'); } return base64_encode; //把json格式转换为base64位,用于传输 }

地点用到了二个自定义的点子hash(卡塔尔,我们得以看下方法的落实。

 protected function hash { // 生成签名 // 1、把随机值转为base64 // 2、使用hash_hmac生成sha256的加密值,用来验证参数是否更改。第一个参数表示加密方式,目前是使用sha256,第二个是用随机值连上加密过后的内容进行,第三个参数是上步使用的key。生成签名。 return hash_hmac('sha256', $iv.$value, $this->key); /根据随机值和内容,生成一个sha256的签名 }

如上加密共分了三大步

框架用到贰个高雅的法门,使用serialize生成三个值,那几个点子高贵在哪个地方,正是不论你得内容是数组依然字符串,都能转换到字符串。
而使用serialize和选择json_encode的分化在哪,笔者想最大的低价是,你所要加密的内容相当大的时候,serialize相对于要快。

除此以外三个地点是,框架在加密的时候使用了二个放肆字符串。为啥要接受随机字符串呢,因为运用了自由字符串,使每趟加密的开始和结果都以不均等的,幸免别人猜出来。

3. 分析decrypt方法

解密数据,能够说是最复杂的一块,不止要举办数量的解密,而且还要保险数据的完整性,以至数额防点窜

public function decrypt($payload, $unserialize = true) { $payload = $this->getJsonPayload; //把加密后的字符串转换出成数组。 $iv = base64_decode; //把随机字符串进行base64解密出来 $decrypted = openssl_decrypt( //解密数据 $payload['value'], $this->cipher, $this->key, 0, $iv ); if  { throw new DecryptException('Could not decrypt the data.'); } return $unserialize ? unserialize : $decrypted; //把数据转换为原始数据 }

getJsonPayload方法

 protected function getJsonPayload { $payload = json_decode(base64_decode; //把数据转换为原来的数组形式 if (! $this->validPayload { //验证是不是数组以及数组里有没有随机字符串,加密后的内容,签名 throw new DecryptException('The payload is invalid.'); } if (! $this->validMac { //验证数据是否被篡改 throw new DecryptException('The MAC is invalid.'); } return $payload; }

validPayload方法就不说了,比较轻便和骨干,珍视就说说validMac验证那块,有限支撑数据不被曲解,这是最注重的

 protected function validMac { $calculated = $this->calculateMac($payload, $bytes = random_bytes; //拿数据和随机值生成一个签名 return hash_equals( //比对上一步生成的签名和下面生成的签名的hash是否一样。 hash_hmac('sha256', $payload['mac'], $bytes, true), $calculated //根据原始数据里的签名在新生成一个签名 ); }

calculateMac方法是为着依据原有数据和无约束值生成多少个签字,然后用那具名再一次生成多个具名

 protected function calculateMac { return hash_hmac( 'sha256', $this->hash($payload['iv'], $payload['value']), $bytes, true ); }

上述解密共分了三大步

1、决断数据的完整性

2、判定数据的大器晚成致性

其风流罗曼蒂克注明具名有个想不到的地点,他并不像大家平日验证具名同样。我们平日验证签名都以,拿原始数据和Infiniti定值生成叁个具名,然后拿生成的签订和原本数据的签订公约举行比对来判定是还是不是有被窜改。

而框架却多了多少个,他用的是,通过原始数据和轻松值生成签名后,又拿这一个签字生成了三个签名,而要比对的也是拿原始数据里的具名在转变二个具名,然后进行比对。近年来想不出,为啥要多几步操作。

在加密的时候,大家把原本数据利用serialize转变了瞬间,所以大家相应的也亟需选拔unserialize把数据转变回来。

注意

加密时使用的openssl_encrypt里的任意项量值是应用的原本数据raw这种二进制的值,使用openssl_decrypt解密后的值是应用的通过base六十一位后的私自字符串。
解密的时候生成签字比较的时候,不是用原本的签定,然后依据原有数据的剧情,重新生成叁次签约实行相比,而是使用原来签字为底工生成二个签约,然后在拿原始数据为根基改变的签字,在用那些新调换的签名重新生成了一遍签订公约。然后开展比较的。
AES256是加密数量,后边可以逆向在进展解密出多少。而SHA256是生成签字的,这几个进程是不可逆的,是为了求证数据的完整性。

总结

上述正是那篇文章的全体内容了,希望本文的内容对大家的就学或然办事能带给一定的佑助,假如有疑点咱们能够留言调换,多谢大家对台本之家的援救。

相关文章

发表评论

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

网站地图xml地图