亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 語言 > PHP > 正文

Laravel中encrypt和decrypt的實現方法

2024-05-05 00:00:14
字體:
來源:轉載
供稿:網友

前言

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('APP_KEY'),   'cipher' => 'AES-256-CBC',

使用方法,在laravel里已經有使用方法了,這里就不在過多的說了。主要使用的兩個方法,一個是encrypt的加密,一個是decrypt的解密

2. 查找加密解密的文件

實現方法的位置是在vendor/illuminate/encryption/的目錄下發現兩個文件,一個是EncryptionServiceProvider另外一個是Encrypter

3. 分析EncryptionServiceProvider文件

 public function register() {  $this->app->singleton('encrypter', function ($app) {   $config = $app->make('config')->get('app'); //從config/app.php里拿到配置文件   if (Str::startsWith($key = $config['key'], 'base64:')) { //分析配置文件里的key里面有沒有帶'base64'    $key = base64_decode(substr($key, 7)); //如果有的話,把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 = (string) $key; //把key轉換為字符串  if (static::supported($key, $cipher)) { //調用一個自定義的方法,用來判斷加密方式和要求的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($key, $cipher) {  $length = mb_strlen($key, '8bit'); //判斷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); //生成一個16位的隨機字符串      // 使用openssl_encrypt把數據生成一個加密的數據  // 1、判斷需要不需要生成一個可存儲表示的值,這樣做是為了不管你的數據是數組還是字符串都能給你轉成一個字符串,不至于在判斷你傳過來的數據是數組還是字符串了。  // 2、使用openssl_encrypt。第一個參數是傳入數據,第二個參數是傳入加密方式,目前使用AES-256-CBC的加密方式,第三個參數是,返回加密后的原始數據,還是把加密的數據在經過一次base64的編碼,0的話表示base64位數據。第四個參數是項量,這個參數傳入隨機數,是為了在加密數據的時候每次的加密數據都不一樣。  $value = /openssl_encrypt(   $serialize ? serialize($value) : $value,   $this->cipher, $this->key, 0, $iv  ); //使用AES256加密內容  if ($value === false) {   throw new EncryptException('Could not encrypt the data.');  }  $mac = $this->hash($iv = base64_encode($iv), $value); //生成一個簽名,用來保證內容參數沒有被更改  $json = json_encode(compact('iv', 'value', 'mac')); //把隨機碼,加密內容,已經簽名,組成數組,并轉成json格式  if (! is_string($json)) {   throw new EncryptException('Could not encrypt the data.');  }  return base64_encode($json); //把json格式轉換為base64位,用于傳輸 }

上面用到了一個自定義的方法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把數據轉換回來。

注意

  • 加密時使用的openssl_encrypt里的隨機項量值是使用的原始數據raw這種二進制的值,使用openssl_decrypt解密后的值是使用的經過base64位后的隨機字符串。
  • 解密的時候生成簽名比較的時候,不是用原來的簽名,然后根據原始數據的內容,重新生成一次簽名進行比較,而是使用原始簽名為基礎生成一個簽名,然后在拿原始數據為基礎生成的簽名,在用這個新生成的簽名重新生成了一次簽名。然后進行比較的。
  • AES256是加密數據,后面能夠逆向在進行解密出數據。而SHA256是生成簽名的,這個過程是不可逆的,是為了驗證數據的完整性。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網的支持。

 

注:相關教程知識閱讀請移步到PHP教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
成人中文字幕+乱码+中文字幕| 精品呦交小u女在线| 亚洲最新中文字幕| 亚洲高清av在线| 亚洲福利视频网站| 日韩大陆毛片av| 亚洲大胆人体av| 91日本视频在线| 在线观看不卡av| 久久影院资源网| 国产一区二区三区毛片| 欧美成人一区二区三区电影| 久久久久久久久久久免费| 95av在线视频| 久久精品国产久精国产一老狼| 欧美极品少妇与黑人| 色偷偷av亚洲男人的天堂| 日本一区二区不卡| 国产精品国产自产拍高清av水多| 亚洲精品在线观看www| 欧美日韩免费网站| 日韩av在线看| 成人免费网视频| 精品夜色国产国偷在线| 少妇高潮久久77777| 亚洲精选在线观看| 亚洲精品成人久久久| 中文欧美日本在线资源| 欧美乱妇高清无乱码| 久久久在线观看| 午夜精品理论片| 国产精品美女久久久久久免费| 午夜精品免费视频| 色偷偷91综合久久噜噜| 国产主播精品在线| 成人乱人伦精品视频在线观看| 成人午夜在线视频一区| 精品亚洲精品福利线在观看| 97精品久久久| 久久久av电影| 川上优av一区二区线观看| 韩国三级日本三级少妇99| 久久精品久久久久久| 国产欧美一区二区三区视频| 国产精品电影久久久久电影网| 韩日欧美一区二区| 伊人久久五月天| 91chinesevideo永久地址| 欧美激情视频免费观看| 国语自产在线不卡| 韩曰欧美视频免费观看| 亚洲天堂影视av| 国产精品极品美女在线观看免费| 国产精品wwww| 国产91精品视频在线观看| 欧美野外猛男的大粗鳮| 国产欧美 在线欧美| 国产精品人人做人人爽| 国产在线拍揄自揄视频不卡99| 久久人体大胆视频| 欧美激情a∨在线视频播放| 91久久久久久久久久久| 亚洲美女免费精品视频在线观看| 亲子乱一区二区三区电影| 午夜精品久久久久久久白皮肤| 亚洲福利视频网站| 成人网页在线免费观看| 欧美理论电影在线播放| 色婷婷av一区二区三区久久| 午夜精品久久久久久99热| 亚洲男人天堂视频| 国产精品1区2区在线观看| 日韩中文字幕精品| 亚洲精品www久久久久久广东| 国产精品成人va在线观看| 欧美午夜宅男影院在线观看| 欧美黑人狂野猛交老妇| 亚洲色图美腿丝袜| 最近中文字幕2019免费| 91亚洲国产成人精品性色| 日韩欧美在线网址| 日本久久久久亚洲中字幕| 91黄色8090| 亚洲第一视频在线观看| 国产69久久精品成人| 久久久精品美女| 91久久久久久久久久久久久| 国产欧美一区二区三区久久人妖| 亚洲一区二区三区在线视频| 日韩欧美一区二区三区| 国产91亚洲精品| 欧美激情第99页| 久久久久久久久综合| 欧美精品日韩三级| 亚洲欧美国产高清va在线播| 欧美在线视频一二三| 亚洲欧美日韩在线一区| 久久久精品一区| 亚洲天堂色网站| 成人免费网站在线| 亚洲a区在线视频| 国产精品大陆在线观看| 欧美精品手机在线| 久久久成人精品视频| 国产精品99久久久久久白浆小说| 欧美剧在线观看| 久久亚洲精品国产亚洲老地址| 久久人人爽人人爽人人片av高清| 久久99国产精品久久久久久久久| 欧美中在线观看| 乱亲女秽乱长久久久| 日韩在线国产精品| 91久久国产婷婷一区二区| 国模吧一区二区| 久久精品视频导航| 欧美成人三级视频网站| 日韩欧美精品网站| 国产国产精品人在线视| 欧美成aaa人片免费看| 亚洲国产美女精品久久久久∴| 91sao在线观看国产| 亚洲综合中文字幕68页| 成人日韩在线电影| 91午夜理伦私人影院| 国产精品成人久久久久| 国产成人精品久久二区二区91| 亚洲最大中文字幕| 亚洲天堂2020| 美女少妇精品视频| 欧美日韩国产成人高清视频| 亚洲欧美日韩中文在线制服| 国产一区二中文字幕在线看| 亚洲国产一区二区三区在线观看| 国产欧美在线观看| 国产香蕉一区二区三区在线视频| 国产最新精品视频| 亚洲成av人片在线观看香蕉| 亚洲欧美日韩高清| 亚洲欧美成人精品| 欧美黑人又粗大| 亚洲男人第一av网站| 国产日韩欧美成人| 日韩视频永久免费观看| 成人情趣片在线观看免费| 欧美综合激情网| 欧美成人中文字幕| 欧美激情第1页| 欧美精品video| 久久亚洲精品视频| 中文字幕日韩欧美精品在线观看| 成人国产亚洲精品a区天堂华泰| 欧美最猛性xxxxx(亚洲精品)| 在线播放国产一区中文字幕剧情欧美| 亚洲精品av在线播放| 精品成人在线视频| 亚洲男人天堂网站| 亚洲福利在线看| 国产美女高潮久久白浆| 国产噜噜噜噜噜久久久久久久久| 国产精品夫妻激情| 欧美激情久久久久久| 日韩精品视频免费专区在线播放| 久久综合伊人77777| 亚洲欧洲在线播放|